本文介绍了如何判断您当前使用的SQL语句能否使用列存索引加速功能。
判断方法
本文的TPC-H的实现基于TPC-H的基准测试,并不能与已发布的TPC-H基准测试结果相比较,本文中的测试并不符合TPC-H基准测试的所有要求。
如何判断您需要查询的列是否被列存索引覆盖,请参考检查SQL语句中的表是否已创建列索引。
列存索引只能访问被列存索引覆盖到的数据列的数据,因此,当您需要查询的列都被列存索引覆盖时,便可以使用列存索引加速功能。
PolarDB MySQL版中,列存执行计划以横向树的格式输出,与行存执行计划的输出格式有一定的区分度,您可以通过查看执行计划的方式来判断某条SQL语句是否可以使用列存索引加速功能。示例如下:
执行如下命令,查看SQL语句的执行计划:
explain SELECT l_orderkey,sum(l_extendedprice * (1 - l_discount)) AS revenue,o_orderdate,o_shippriority FROM customer,orders,lineitem WHERE c_mktsegment = 'BUILDING' AND c_custkey = o_custkey AND l_orderkey = o_orderkey AND o_orderdate < date '1995-03-24' AND l_shipdate > date '1995-03-24' GROUP BY l_orderkey,o_orderdate,o_shippriority ORDER BY revenue DESC,o_orderdate\G;
行存执行计划显示结果如下:
+----+-------------+----------+------------+--------+---------------+---------+---------+--------------------------+---------+----------+----------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+--------+---------------+---------+---------+--------------------------+---------+----------+----------------------------------------------+ | 1 | SIMPLE | orders | NULL | ALL | PRIMARY | NULL | NULL | NULL | 1482516 | 33.33 | Using where; Using temporary; Using filesort | | 1 | SIMPLE | customer | NULL | eq_ref | PRIMARY | PRIMARY | 8 | tpch1g.orders.O_CUSTKEY | 1 | 10.00 | Using where | | 1 | SIMPLE | lineitem | NULL | ref | PRIMARY | PRIMARY | 8 | tpch1g.orders.O_ORDERKEY | 3 | 33.33 | Using where | +----+-------------+----------+------------+--------+---------------+---------+---------+--------------------------+---------+----------+----------------------------------------------+ 3 rows in set, 1 warning (0.01 sec)
列存执行计划显示结果如下:
*************************** 1. row *************************** IMCI Execution Plan (max_dop = 8, max_query_mem = 3435134976): Project | Exprs: temp_table3.lineitem.L_ORDERKEY, temp_table3.SUM(lineitem.L_EXTENDEDPRICE * 1.00 - lineitem.L_DISCOUNT), temp_table3.orders.O_ORDERDATE, temp_table3.orders.O_SHIPPRIORITY Sort | Exprs: temp_table3.SUM(lineitem.L_EXTENDEDPRICE * 1.00 - lineitem.L_DISCOUNT) DESC,temp_table3.orders.O_ORDERDATE ASC HashGroupby | OutputTable(3): temp_table3 | Grouping: lineitem.L_ORDERKEY orders.O_ORDERDATE orders.O_SHIPPRIORITY | Output Grouping: lineitem.L_ORDERKEY, orders.O_ORDERDATE, orders.O_SHIPPRIORITY | Aggrs: SUM(lineitem.L_EXTENDEDPRICE * 1.00 - lineitem.L_DISCOUNT) HashJoin | HashMode: DYNAMIC | JoinMode: INNER | JoinPred: orders.O_ORDERKEY = lineitem.L_ORDERKEY HashJoin | HashMode: DYNAMIC | JoinMode: INNER | JoinPred: orders.O_CUSTKEY = customer.C_CUSTKEY CTableScan | InputTable(0): orders | Pred: (orders.O_ORDERDATE < 03/24/1995 00:00:00.000000) CTableScan | InputTable(1): customer | Pred: (customer.C_MKTSEGMENT = "BUILDING") CTableScan | InputTable(2): lineitem | Pred: (lineitem.L_SHIPDATE > 03/24/1995 00:00:00.000000) 1 row in set (0.04 sec)
FAQ
当某条SQL语句的执行计划不是列存执行计划时,可能的原因有哪些?
SQL语句查询的数据列是否被列存索引覆盖,若数据列没有被列存索引覆盖,请为需要使用列存执行计划的数据列创建列存索引,创建列存索引请参见建表时创建列存索引的DDL语法或动态增加或删除列存索引的DDL语法。
对于已开启行存/列存自动引流的集群地址,请确认参数设置中的
loose_imci_ap_threshold
参数值是否满足条件,即检查SHOW STATUS LIKE 'Last_query_cost'
的值是否大于SHOW VARIABLES LIKE 'imci_ap_threshold'
的值。若不满足,请参考配置自动引流阈值中的内容适当修改loose_imci_ap_threshold
参数值。对于只读列存节点, 请确认参数设置中的
loose_cost_threshold_for_imci
参数值是否满足条件,即检查SHOW STATUS LIKE 'Last_query_cost'
的值是否大于SHOW VARIABLES LIKE 'cost_threshold_for_imci'
的值。若不满足,请参考配置自动引流阈值中的内容适当修改loose_cost_threshold_for_imci
参数值。对于主节点、普通列存节点或未开启行存/列存自动引流的集群地址,请切换至开启行存/列存自动引流的集群地址或者直接连接只读列存节点。