我在这篇文章中的目标是仅提供所需的信息,并查看是否可以优化此查询。这是查询本身:
FLUSH TABLES;
SELECT SQL_CALC_FOUND_ROWS
nl.id,
nl.node_id,
nl.name,
nl.parent_name,
nlv.status,
nlv.version,
nlv.code,
nlv.region_id AS region
-- added fields if specified
,IF(ISNULL(nf_youtube_id.value), '', nf_youtube_id.value) AS youtube_id
,IF(ISNULL(nf_brightcove_id.value), '', nf_brightcove_id.value) AS brightcove_id
,IF(ISNULL(nf_youku_id.value), '', nf_youku_id.value) AS youku_id
FROM
node_lists nl
JOIN node_list_versions nlv ON nlv.node_list_id = nl.id
JOIN node_versions nv ON nl.node_id = nv.node_id AND nlv.region_id = nv.region_id
-- added field joins if specified
LEFT JOIN node_fields nf_youtube_id ON nf_youtube_id.node_version_id = nv.id AND nf_youtube_id.name = 'youtube_id'
LEFT JOIN node_fields nf_brightcove_id ON nf_brightcove_id.node_version_id = nv.id AND nf_brightcove_id.name = 'brightcove_id'
LEFT JOIN node_fields nf_youku_id ON nf_youku_id.node_version_id = nv.id AND nf_youku_id.name = 'youku_id'
WHERE
nl.model_type = 'Resource'
AND ((nl.name LIKE '%') OR (nlv.code LIKE '%'))
GROUP BY
nl.node_id, nlv.region_id
ORDER BY
status asc LIMIT 0, 1000000
所以表格上的统计数据是:
node_lists
:innoDB,10,400条记录
node_list_versions
:innoDB,199,600条记录
node_versions
:innoDB,12,065条记录
node_fields
:innoDB,205,900条记录
尽管所有表都是innoDB,但密钥之间没有实际约束。没有REFERENCES
,ON UPDATE CASCADE等。我在所有join和where子句字段上都有btree
索引(我理解的很多)。
查询大约需要2.5秒,没有来自node_fields
表的连接/字段,LEFT JOIN
每个node_fields
实例的EXPLAIN (that query)
会在此特定查询上增加大约半秒。
我能做些什么来优化这个查询,特别是任何明显的遗漏?作为参考,select_type table type possible_keys key key_len ref rows filt Extra
SIMPLE nl ref PRIMARY,node_lists_model_type_index,node_lists_node_id_index node_lists_model_type_index 194 const 7624 100 Using temporary; Using filesort
SIMPLE nv ref node_versions_node_id_index,node_versions_region_id_index node_versions_node_id_index 4 db.nl.node_id 1 100 NULL
SIMPLE nlv ref node_list_region_node_list_id_index,node_list_region_region_id_index node_list_region_node_list_id_index 4 db.nl.id 17 6.25 Using where
SIMPLE nf_youtube_id ref node_fields_node_version_id_index,node_fields_name_index node_fields_node_version_id_index 4 db.nv.id 7 100 Using where
SIMPLE nf_brightcove_id ref node_fields_node_version_id_index,node_fields_name_index node_fields_node_version_id_index 4 db.nv.id 7 100 Using where
SIMPLE nf_youku_id ref node_fields_node_version_id_index,node_fields_name_index node_fields_node_version_id_index 4 db.nv.id 7 100 Using where
得出以下结论:
LEFT JOIN
我无法看到我在哪里丢失任何内容或索引不完整。 node_fields
Lista
的{{1}}似乎只有0.5秒。我怎样才能改善这个?