优化利用实体属性值(EAV)表的SQL查询,这会增加大量时间

时间:2017-06-18 12:45:49

标签: mysql sql optimization relational

我在这篇文章中的目标是仅提供所需的信息,并查看是否可以优化此查询。这是查询本身:

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秒。我怎样才能改善这个?

0 个答案:

没有答案