我正在尝试优化在我们的平台中使用Apache Phoenix和HBase的性能。一个关键查询,称为Q,需要两个表之间的连接,我们称之为X和Y.X包含150,000,000行,Y包含20,000行。
Q的解释计划如下:
客户端22-CHUNK并行扫描完全扫描22次 一些过滤
一些聚合客户端MERGE SORT
并行内联表0 客户1-CHUNK并行单向跳过2个按键扫描[11,000,000,433,043] - [11,000,000,433,115]
一些过滤
我能够设计另一个查询,称之为Q *,创建与Q相同的输出,并使用Phoenix的Skip Scan。
这个想法是确定事先执行查询所需的主键,并将Q修改为Q *,以便Phoenix可以确定在必要的主键范围上使用Skip Scan。
Q *的解释计划如下:
客户13-CHUNK并行X方式跳过1个范围X-X [10,100,000,034,326,4] - [10,100,002,330,223,4]
一些过滤
一些聚合客户端MERGE SORT
并行内联表0 客户1-CHUNK并行单向跳过2个按键扫描[11,000,000,433,043] - [11,000,000,433,115]
一些过滤
但是,在测试这两个查询的性能时,我发现Q *平均花费的时间约为Q的1.5倍。
结果:
Q *结果:平均:9739 |分:9174 |最大值:11117
Q结果:平均:6393 |分:6128 |最大值:6966
我可以看到Q *使用的线程少于Q,但这是有道理的,因为Q *读取的块比Q少。所以我不认为这是原因。
然而,确定Q *的主键范围(这也是凤凰查询)所需的操作可能是罪魁祸首,但我不相信。
对凤凰城内部运作的任何见解都解释了这种看似更有效的HBase操作缺乏改进的性能。
示例凤凰查询Q和Q *如下。
提前致谢。
问:
SELECT AH.date,
M.groupKey, AH.classType,
AH.prodType, AH.liabType, AH.feeType,
AH.currency, SUM(AH.feeAccrued),
SUM(AH.accruedAmt), SUM(AH.totalMktValue),
SUM(AH.mktValue), SUM (AH.cashFlowAmt),
SUM(AH.wtCashFlowAmt), SUM(0) AS uvAmount
FROM **X** AH JOIN **Y** M
ON M.accountKey = AH.accountKey
WHERE M.groupKey IN (11000000433043,11000000433115)
AND AH.accountKey =M.accountKey
AND classType= 4
AND AH.date > 20021231
AND AH.date <= 20171030
AND (AH.deleteFlag IS NULL OR AH.deleteFlag = 'N')
AND AH.reconFlag = 'Y' AND AH.reconActivity = 'Y'
AND M.etlTag = 'TEST'
GROUP BY AH.date,
M.groupKey , AH.classType,
AH.prodType, AH.liabType, AH.feeType,
AH.liabType,AH.currency
问*:
SELECT AH.date,
M.groupKey, AH.classType,
AH.prodType, AH.liabType, AH.feeType,
AH.currency, SUM(AH.feeAccrued),
SUM(AH.accruedAmt), SUM(AH.totalMktValue),
SUM(AH.mktValue), SUM (AH.cashFlowAmt),
SUM(AH.wtCashFlowAmt), SUM(0) AS uvAmount
FROM **X** AH JOIN **Y** M
ON M.accountKey = AH.accountKey
WHERE M.groupKey IN (11000000433043,11000000433115)
AND AH.accountKey =M.accountKey
***AND AH.accountKey <= 10100002330223
AND AH.accountKey >= 10100000034326***
AND classType= 4
AND AH.date > 20021231
AND AH.date <= 20171030
AND (AH.deleteFlag IS NULL OR AH.deleteFlag = 'N')
AND AH.reconFlag = 'Y' AND AH.reconActivity = 'Y'
AND M.etlTag = 'TEST'
GROUP BY AH.date,
M.groupKey , AH.classType,
AH.prodType, AH.liabType, AH.feeType,
AH.liabType,AH.currency