oxn*_*xnz 6 mysql sql join inner-join query-optimization
最近我想出了一些mysql性能问题,这里是查询:
select
assoc.id as id,
parentNode.id as parentNodeId,
parentNode.version as parentNodeVersion,
parentStore.protocol as parentNodeProtocol,
parentStore.identifier as parentNodeIdentifier,
parentNode.uuid as parentNodeUuid,
childNode.id as childNodeId,
childNode.version as childNodeVersion,
childStore.protocol as childNodeProtocol,
childStore.identifier as childNodeIdentifier,
childNode.uuid as childNodeUuid,
assoc.type_qname_id as type_qname_id,
assoc.child_node_name_crc as child_node_name_crc,
assoc.child_node_name as child_node_name,
assoc.qname_ns_id as qname_ns_id,
assoc.qname_localname as qname_localname,
assoc.is_primary as is_primary,
assoc.assoc_index as assoc_index
from
alf_child_assoc assoc
join alf_node parentNode on (parentNode.id = assoc.parent_node_id)
join alf_store parentStore on (parentStore.id = parentNode.store_id)
join alf_node childNode on (childNode.id = assoc.child_node_id)
join alf_store childStore on (childStore.id = childNode.store_id)
where
parentNode.id = 837
order by
assoc.assoc_index ASC,
assoc.id ASC;
Run Code Online (Sandbox Code Playgroud)
问题是查询需要太长的排序和发送结果集.任何帮助表示赞赏,提前谢谢
一些计数信息:
mysql> select count(id) from alf_child_assoc;
+-----------+
| count(id) |
+-----------+
| 7208882 |
+-----------+
1 row in set (12.51 sec)
mysql> select count(id) from alf_node;
+-----------+
| count(id) |
+-----------+
| 3986059 |
+-----------+
1 row in set (1.68 sec)
mysql> select count(id) from alf_store;
+-----------+
| count(id) |
+-----------+
| 6 |
+-----------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
这是explain
输出:
+----+-------------+-------------+--------+---------------------------------------------------------------------+----------------+---------+--------------------------+--------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+---------------------------------------------------------------------+----------------+---------+--------------------------+--------+----------------+
| 1 | SIMPLE | parentNode | const | PRIMARY,store_id,fk_alf_node_store,will_store_node_idx | PRIMARY | 8 | const | 1 | Using filesort |
| 1 | SIMPLE | parentStore | const | PRIMARY | PRIMARY | 8 | const | 1 | |
| 1 | SIMPLE | assoc | ref | parent_node_id,fk_alf_cass_pnode,fk_alf_cass_cnode,idx_alf_cass_pri | parent_node_id | 8 | const | 275218 | Using where |
| 1 | SIMPLE | childNode | eq_ref | PRIMARY,store_id,fk_alf_node_store,will_store_node_idx | PRIMARY | 8 | repo.assoc.child_node_id | 1 | |
| 1 | SIMPLE | childStore | eq_ref | PRIMARY | PRIMARY | 8 | repo.childNode.store_id | 1 | |
+----+-------------+-------------+--------+---------------------------------------------------------------------+----------------+---------+--------------------------+--------+----------------+
5 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
下面是一些与表相关的信息:
mysql> desc alf_child_assoc;
+---------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| parent_node_id | bigint(20) | NO | MUL | NULL | |
| type_qname_id | bigint(20) | NO | MUL | NULL | |
| child_node_name_crc | bigint(20) | NO | | NULL | |
| child_node_name | varchar(50) | NO | | NULL | |
| child_node_id | bigint(20) | NO | MUL | NULL | |
| qname_ns_id | bigint(20) | NO | MUL | NULL | |
| qname_localname | varchar(255) | NO | | NULL | |
| qname_crc | bigint(20) | NO | MUL | NULL | |
| is_primary | bit(1) | YES | | NULL | |
| assoc_index | int(11) | YES | MUL | NULL | |
+---------------------+--------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)
mysql> desc alf_node;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| store_id | bigint(20) | NO | MUL | NULL | |
| uuid | varchar(36) | NO | | NULL | |
| transaction_id | bigint(20) | NO | MUL | NULL | |
| node_deleted | bit(1) | NO | MUL | NULL | |
| type_qname_id | bigint(20) | NO | MUL | NULL | |
| locale_id | bigint(20) | NO | MUL | NULL | |
| acl_id | bigint(20) | YES | MUL | NULL | |
| audit_creator | varchar(255) | YES | | NULL | |
| audit_created | varchar(30) | YES | | NULL | |
| audit_modifier | varchar(255) | YES | | NULL | |
| audit_modified | varchar(30) | YES | | NULL | |
| audit_accessed | varchar(30) | YES | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
14 rows in set (0.00 sec)
mysql> desc alf_store;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| protocol | varchar(50) | NO | MUL | NULL | |
| identifier | varchar(100) | NO | | NULL | |
| root_node_id | bigint(20) | YES | MUL | NULL | |
+--------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql>
mysql> show index from alf_node;
+----------+------------+----------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| alf_node | 0 | PRIMARY | 1 | id | A | 3890448 | NULL | NULL | | BTREE | | |
| alf_node | 0 | store_id | 1 | store_id | A | 18 | NULL | NULL | | BTREE | | |
| alf_node | 0 | store_id | 2 | uuid | A | 3890448 | NULL | NULL | | BTREE | | |
| alf_node | 1 | idx_alf_node_del | 1 | node_deleted | A | 18 | NULL | NULL | | BTREE | | |
| alf_node | 1 | idx_alf_node_txn_del | 1 | transaction_id | A | 3890448 | NULL | NULL | | BTREE | | |
| alf_node | 1 | idx_alf_node_txn_del | 2 | node_deleted | A | 3890448 | NULL | NULL | | BTREE | | |
| alf_node | 1 | fk_alf_node_acl | 1 | acl_id | A | 3890448 | NULL | NULL | YES | BTREE | | |
| alf_node | 1 | fk_alf_node_txn | 1 | transaction_id | A | 3890448 | NULL | NULL | | BTREE | | |
| alf_node | 1 | fk_alf_node_store | 1 | store_id | A | 18 | NULL | NULL | | BTREE | | |
| alf_node | 1 | fk_alf_node_tqn | 1 | type_qname_id | A | 18 | NULL | NULL | | BTREE | | |
| alf_node | 1 | fk_alf_node_loc | 1 | locale_id | A | 18 | NULL | NULL | | BTREE | | |
| alf_node | 1 | will_store_node_idx | 1 | id | A | 3890448 | NULL | NULL | | BTREE | | |
| alf_node | 1 | will_store_node_idx | 2 | store_id | A | 3890448 | NULL | NULL | | BTREE | | |
+----------+------------+----------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
13 rows in set (0.01 sec)
mysql> show index from alf_store;
+-----------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| alf_store | 0 | PRIMARY | 1 | id | A | 6 | NULL | NULL | | BTREE | | |
| alf_store | 0 | protocol | 1 | protocol | A | 6 | NULL | NULL | | BTREE | | |
| alf_store | 0 | protocol | 2 | identifier | A | 6 | NULL | NULL | | BTREE | | |
| alf_store | 1 | fk_alf_store_root | 1 | root_node_id | A | 6 | NULL | NULL | YES | BTREE | | |
+-----------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)
mysql> show index from alf_child_assoc;
+-----------------+------------+--------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+--------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| alf_child_assoc | 0 | PRIMARY | 1 | id | A | 6956126 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 0 | parent_node_id | 1 | parent_node_id | A | 632375 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 0 | parent_node_id | 2 | type_qname_id | A | 632375 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 0 | parent_node_id | 3 | child_node_name_crc | A | 6956126 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 0 | parent_node_id | 4 | child_node_name | A | 6956126 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | fk_alf_cass_pnode | 1 | parent_node_id | A | 695612 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | fk_alf_cass_cnode | 1 | child_node_id | A | 6956126 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | fk_alf_cass_tqn | 1 | type_qname_id | A | 16 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | fk_alf_cass_qnns | 1 | qname_ns_id | A | 16 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | idx_alf_cass_qncrc | 1 | qname_crc | A | 3478063 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | idx_alf_cass_qncrc | 2 | type_qname_id | A | 6956126 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | idx_alf_cass_qncrc | 3 | parent_node_id | A | 6956126 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | idx_alf_cass_pri | 1 | parent_node_id | A | 1159354 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | idx_alf_cass_pri | 2 | is_primary | A | 1159354 | NULL | NULL | YES | BTREE | | |
| alf_child_assoc | 1 | idx_alf_cass_pri | 3 | child_node_id | A | 6956126 | NULL | NULL | | BTREE | | |
| alf_child_assoc | 1 | will_order_idx | 1 | assoc_index | A | 16 | NULL | NULL | YES | BTREE | | |
| alf_child_assoc | 1 | will_order_idx | 2 | id | A | 6956126 | NULL | NULL | | BTREE | | |
+-----------------+------------+--------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
17 rows in set (0.16 sec)
Run Code Online (Sandbox Code Playgroud)
在阅读@ Solarflare的回答后,我试了一下,现在查询变为:
SELECT STRAIGHT_JOIN
assoc.id AS id,
parentNode.id AS parentNodeId,
parentNode.version AS parentNodeVersion,
parentStore.protocol AS parentNodeProtocol,
parentStore.identifier AS parentNodeIdentifier,
parentNode.uuid AS parentNodeUuid,
childNode.id AS childNodeId,
childNode.version AS childNodeVersion,
childStore.protocol AS childNodeProtocol,
childStore.identifier AS childNodeIdentifier,
childNode.uuid AS childNodeUuid,
assoc.type_qname_id AS type_qname_id,
assoc.child_node_name_crc AS child_node_name_crc,
assoc.child_node_name AS child_node_name,
assoc.qname_ns_id AS qname_ns_id,
assoc.qname_localname AS qname_localname,
assoc.is_primary AS is_primary,
assoc.assoc_index AS assoc_index
FROM
alf_child_assoc assoc FORCE INDEX (will_subq_idx)
JOIN
alf_node parentNode ON (parentNode.id = assoc.parent_node_id)
JOIN
alf_node childNode ON (childNode.id = assoc.child_node_id)
JOIN
alf_store parentStore ON (parentStore.id = parentNode.store_id)
JOIN
alf_store childStore ON (childStore.id = childNode.store_id)
WHERE
parentNode.id = 550
ORDER BY assoc.assoc_index ASC , assoc.id ASC;
Run Code Online (Sandbox Code Playgroud)
并且解释显示:
+----+-------------+-------------+------------+--------+-----------------------------------------------------------------------+---------------+---------+--------------------------+--------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+--------+-----------------------------------------------------------------------+---------------+---------+--------------------------+--------+----------+---------------------------------------+
| 1 | SIMPLE | assoc | NULL | ref | will_subq_idx | will_subq_idx | 8 | const | 303104 | 100.00 | Using index condition; Using filesort |
| 1 | SIMPLE | parentNode | NULL | const | PRIMARY,store_id,fk_alf_node_store,will_store_node_idx,will_store_idx | PRIMARY | 8 | const | 1 | 100.00 | NULL |
| 1 | SIMPLE | childNode | NULL | eq_ref | PRIMARY,store_id,fk_alf_node_store,will_store_node_idx,will_store_idx | PRIMARY | 8 | repo.assoc.child_node_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | parentStore | NULL | eq_ref | PRIMARY,will_store_idx | PRIMARY | 8 | repo.parentNode.store_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | childStore | NULL | eq_ref | PRIMARY,will_store_idx | PRIMARY | 8 | repo.childNode.store_id | 1 | 100.00 | NULL |
+----+-------------+-------------+------------+--------+-----------------------------------------------------------------------+---------------+---------+--------------------------+--------+----------+---------------------------------------+
5 rows in set, 1 warning (0.03 sec)
Run Code Online (Sandbox Code Playgroud)
这是mysql workbench显示的查询计划:
谢谢你们,你真棒!
您可以将单个大型查询拆分为临时表中的多个部分,然后合并最终结果集。
with tmp1 as (
SELECT table1.column1, table2.column2...
FROM table1 JOIN table2
ON table1.common_field = table2.common_field),
tmp2 as (
SELECT table3.column1, table4.column2...
FROM table3 JOIN table4
ON table3.common_field = table4.common_field)
select a.column1, a.column2, b.column1, b.column2 .. from tmp1 a join tmp2 b on a.Something = b.Something;
Run Code Online (Sandbox Code Playgroud)