我在 Drupal 7 上有一个查询,运行时间超过 60 秒。有很多连接,但所有连接的项目都有索引(BTREE),所以我不确定为什么它们运行得这么慢。也许这就是它的方式?我不是 DBA,也不是此查询的开发人员,但我正在尝试诊断瓶颈,因为当我们遇到大问题时,例如,Google 为我们编制索引。
感谢您提供的任何帮助。
* 更新查询和解释 请注意,在进行建议的更改后,我至少能够将处理时间缩短约 20%。它仍然很慢,但越来越快。 where 和 order by 子句中的所有字段都有索引。另外,我不确定我如何才能停止使用“!=”而不是 in。我当然愿意接受建议。最后,我也不确定如何让它停止使用文件排序或尊重我的索引。如果您认为有帮助,我很乐意发布这些索引 :) 感谢大家到目前为止的帮助! *
SELECT
n.type AS type,
CASE
WHEN n.type = 'book_new' THEN workid.field_workid_target_id
ELSE n.nid
END AS uuid,
CASE
WHEN n.type = 'book_new' THEN UNIX_TIMESTAMP(MIN(sale_date.field_onsaledate_value))
ELSE n.created
END AS sort_date
FROM
node n
LEFT OUTER JOIN
field_data_field_related_books books ON n.nid = books.entity_id
LEFT OUTER JOIN
field_data_field_author_ref author_refs ON books.entity_id = author_refs.entity_id
LEFT OUTER JOIN
field_data_field_workid workid ON n.nid = workid.entity_id
LEFT OUTER JOIN
field_data_field_onsaledate sale_date ON workid.entity_id = sale_date.entity_id
LEFT OUTER JOIN
field_data_field_format format ON sale_date.entity_id = format.entity_id
LEFT OUTER JOIN
field_data_field_subjectcategories subjects ON format.entity_id = subjects.entity_id
AND subjects.field_subjectcategories_tid = '48981'
LEFT OUTER JOIN
field_data_field_subjectcategories subjects2 ON subjects.entity_id = subjects2.entity_id
AND subjects2.field_subjectcategories_tid = '54556'
LEFT OUTER JOIN
field_data_field_subjectcategories subjects3 ON subjects2.entity_id = subjects3.entity_id
AND subjects3.field_subjectcategories_tid = '61091'
WHERE
((books.field_related_books_target_id IN ('874271'))
OR (author_refs.field_author_ref_target_id IN ('874561' , '572716', '874551'))
OR (((subjects.field_subjectcategories_tid IS NOT NULL)
AND (subjects2.field_subjectcategories_tid IS NOT NULL))
OR ((subjects2.field_subjectcategories_tid IS NOT NULL)
AND (subjects3.field_subjectcategories_tid IS NOT NULL))
OR ((subjects.field_subjectcategories_tid IS NOT NULL)
AND (subjects3.field_subjectcategories_tid IS NOT NULL))))
AND (n.status = '1')
AND (n.type != 'wow')
AND (n.type != 'event')
AND (n.type != 'slice')
AND (n.nid NOT IN ('874271'))
AND (sale_date.field_onsaledate_value < CURDATE()
OR sale_date.field_onsaledate_value IS NULL)
AND ((format.field_format_tid NOT IN ('2296' , '4986', '1641', '1756'))
OR (format.field_format_tid IS NULL))
GROUP BY uuid
ORDER BY books.field_related_books_target_id = 874271 DESC ,
author_refs.field_author_ref_target_id = 874561 DESC ,
author_refs.field_author_ref_target_id = 572716 DESC ,
author_refs.field_author_ref_target_id = 874551 DESC ,
sort_date DESC
LIMIT 36 OFFSET 35;
+----+-------------+-------------+------+---------------------------------------+------------------+---------+---------------------------+--------+----------+--------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------+---------------------------------------+------------------+---------+---------------------------+--------+----------+--------------------------------------------------------+
| 1 | SIMPLE | n | ref | PRIMARY,node_status_type,node_type | node_status_type | 4 | const | 342627 | 100 | Using index condition; Using temporary; Using filesort |
| 1 | SIMPLE | books | ref | entity_id | entity_id | 4 | prhc2.n.nid | 1 | 100 | NULL |
| 1 | SIMPLE | author_refs | ref | entity_id | entity_id | 4 | prhc2.books.entity_id | 1 | 100 | NULL |
| 1 | SIMPLE | workid | ref | entity_id | entity_id | 4 | prhc2.n.nid | 1 | 100 | NULL |
| 1 | SIMPLE | sale_date | ref | entity_id | entity_id | 4 | prhc2.workid.entity_id | 1 | 100 | Using where |
| 1 | SIMPLE | format | ref | entity_id | entity_id | 4 | prhc2.sale_date.entity_id | 1 | 100 | Using where |
| 1 | SIMPLE | subjects | ref | entity_id,field_subjectcategories_tid | entity_id | 4 | prhc2.format.entity_id | 1 | 100 | Using where |
| 1 | SIMPLE | subjects2 | ref | entity_id,field_subjectcategories_tid | entity_id | 4 | prhc2.subjects.entity_id | 1 | 100 | Using where |
| 1 | SIMPLE | subjects3 | ref | entity_id,field_subjectcategories_tid | entity_id | 4 | prhc2.subjects2.entity_id | 1 | 100 | Using where |
+----+-------------+-------------+------+---------------------------------------+------------------+---------+---------------------------+--------+----------+--------------------------------------------------------+
describe node;
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| nid | int(10) unsigned | NO | PRI | NULL | auto_increment |
| vid | int(10) unsigned | YES | UNI | NULL | |
| type | varchar(32) | NO | MUL | | |
| language | varchar(12) | NO | MUL | | |
| title | varchar(255) | NO | MUL | | |
| uid | int(11) | NO | MUL | 0 | |
| status | int(11) | NO | MUL | 1 | |
| created | int(11) | NO | MUL | 0 | |
| changed | int(11) | NO | MUL | 0 | |
| comment | int(11) | NO | | 0 | |
| promote | int(11) | NO | MUL | 0 | |
| sticky | int(11) | NO | | 0 | |
| tnid | int(10) unsigned | NO | MUL | 0 | |
| translate | int(11) | NO | MUL | 0 | |
| downgrade | int(11) | NO | | 0 | |
+-----------+------------------+------+-----+---------+----------------+
describe field_data_field_related_books;
+-------------------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------------+------------------+------+-----+---------+-------+
| entity_type | varchar(128) | NO | PRI | | |
| bundle | varchar(128) | NO | MUL | | |
| deleted | tinyint(4) | NO | PRI | 0 | |
| entity_id | int(10) unsigned | NO | PRI | NULL | |
| revision_id | int(10) unsigned | YES | MUL | NULL | |
| language | varchar(32) | NO | PRI | | |
| delta | int(10) unsigned | NO | PRI | NULL | |
| field_related_books_target_id | int(10) unsigned | NO | MUL | NULL | |
+-------------------------------+------------------+------+-----+---------+-------+
describe field_data_field_author_ref;
+----------------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+------------------+------+-----+---------+-------+
| entity_type | varchar(128) | NO | PRI | | |
| bundle | varchar(128) | NO | MUL | | |
| deleted | tinyint(4) | NO | PRI | 0 | |
| entity_id | int(10) unsigned | NO | PRI | NULL | |
| revision_id | int(10) unsigned | YES | MUL | NULL | |
| language | varchar(32) | NO | PRI | | |
| delta | int(10) unsigned | NO | PRI | NULL | |
| field_author_ref_target_id | int(10) unsigned | NO | MUL | NULL | |
+----------------------------+------------------+------+-----+---------+-------+
describe field_data_field_workid;
+------------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+------------------+------+-----+---------+-------+
| entity_type | varchar(128) | NO | PRI | | |
| bundle | varchar(128) | NO | MUL | | |
| deleted | tinyint(4) | NO | PRI | 0 | |
| entity_id | int(10) unsigned | NO | PRI | NULL | |
| revision_id | int(10) unsigned | YES | MUL | NULL | |
| language | varchar(32) | NO | PRI | | |
| delta | int(10) unsigned | NO | PRI | NULL | |
| field_workid_target_id | int(10) unsigned | NO | MUL | NULL | |
+------------------------+------------------+------+-----+---------+-------+
describe field_data_field_onsaledate;
+------------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+------------------+------+-----+---------+-------+
| entity_type | varchar(128) | NO | PRI | | |
| bundle | varchar(128) | NO | MUL | | |
| deleted | tinyint(4) | NO | PRI | 0 | |
| entity_id | int(10) unsigned | NO | PRI | NULL | |
| revision_id | int(10) unsigned | YES | MUL | NULL | |
| language | varchar(32) | NO | PRI | | |
| delta | int(10) unsigned | NO | PRI | NULL | |
| field_onsaledate_value | datetime | YES | | NULL | |
+------------------------+------------------+------+-----+---------+-------+
describe field_data_field_format;
+------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+-------+
| entity_type | varchar(128) | NO | PRI | | |
| bundle | varchar(128) | NO | MUL | | |
| deleted | tinyint(4) | NO | PRI | 0 | |
| entity_id | int(10) unsigned | NO | PRI | NULL | |
| revision_id | int(10) unsigned | YES | MUL | NULL | |
| language | varchar(32) | NO | PRI | | |
| delta | int(10) unsigned | NO | PRI | NULL | |
| field_format_tid | int(10) unsigned | YES | MUL | NULL | |
+------------------+------------------+------+-----+---------+-------+
describe field_data_field_subjectcategories;
+-----------------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+------------------+------+-----+---------+-------+
| entity_type | varchar(128) | NO | PRI | | |
| bundle | varchar(128) | NO | MUL | | |
| deleted | tinyint(4) | NO | PRI | 0 | |
| entity_id | int(10) unsigned | NO | PRI | NULL | |
| revision_id | int(10) unsigned | YES | MUL | NULL | |
| language | varchar(32) | NO | PRI | | |
| delta | int(10) unsigned | NO | PRI | NULL | |
| field_subjectcategories_tid | int(10) unsigned | YES | MUL | NULL | |
+-----------------------------+------------------+------+-----+---------+-------+
最佳答案
我对连接的顺序做了一些更改,我不确定这是否与速度慢有关,但是当连接多个表时,我尝试以一种逻辑方式将它们链接起来,从第一个表开始并移动到下一个,下一个,下一个,...我不会从较早的连接跳回到同一个表,除非它是自连接并且我给它起了别名。如果您更好地组织它们,它将帮助您更好地跟踪您的连接,这里是:
SELECT
n.type AS type,
CASE
WHEN n.type = 'book_new' THEN workid.field_workid_target_id
ELSE n.nid
END AS uuid,
CASE
WHEN n.type = 'book_new' THEN UNIX_TIMESTAMP(MIN(sale_date.field_onsaledate_value))
ELSE n.created
END AS sort_date
FROM
node n
LEFT OUTER JOIN
field_data_field_related_books books ON n.nid = books.entity_id
LEFT OUTER JOIN
field_data_field_author_ref author_refs ON books.entity_id = author_refs.entity_id
LEFT OUTER JOIN
field_data_field_workid workid ON workid.nid = author_refs.entity_id
LEFT OUTER JOIN
field_data_field_onsaledate sale_date ON workid.entity_id = sale_date.entity_id
LEFT OUTER JOIN
field_data_field_format format ON sale_date.entity_id = format.entity_id
LEFT OUTER JOIN
field_data_field_subjectcategories subjects ON format.entity_id = subjects.entity_id
AND subjects.field_subjectcategories_tid = '48981'
LEFT OUTER JOIN
field_data_field_subjectcategories subjects2 ON subjects.entity_id = subjects2.entity_id
AND subjects2.field_subjectcategories_tid = '54556'
LEFT OUTER JOIN
field_data_field_subjectcategories subjects3 ON subjects2.entity_id = subjects3.entity_id
AND subjects3.field_subjectcategories_tid = '61091'
WHERE
((books.field_related_books_target_id IN ('874271'))
OR (author_refs.field_author_ref_target_id IN ('874561' , '572716', '874551'))
OR (((subjects.field_subjectcategories_tid IS NOT NULL)
AND (subjects2.field_subjectcategories_tid IS NOT NULL))
OR ((subjects2.field_subjectcategories_tid IS NOT NULL)
AND (subjects3.field_subjectcategories_tid IS NOT NULL))
OR ((subjects.field_subjectcategories_tid IS NOT NULL)
AND (subjects3.field_subjectcategories_tid IS NOT NULL))))
AND (n.status = '1')
AND (n.nid NOT IN ('874271'))
AND (n.type != 'wow')
AND (n.type != 'event')
AND (n.type != 'slice')
AND (sale_date.field_onsaledate_value < CURDATE()
OR sale_date.field_onsaledate_value IS NULL)
AND ((format.field_format_tid NOT IN ('2296' , '4986', '1641', '1756'))
OR (format.field_format_tid IS NULL))
GROUP BY uuid
ORDER BY books.field_related_books_target_id = 874271 DESC , author_refs.field_author_ref_target_id = 874561 DESC , author_refs.field_author_ref_target_id = 572716 DESC , author_refs.field_author_ref_target_id = 874551 DESC , sort_date DESC
LIMIT 36 OFFSET 35;
我要检查的另一件事是您在表上的索引。所有那些条件应该被索引的。索引是另一件必须正确完成的事情,您不想做得太过分并且希望它符合逻辑,顺序会有所不同。
我在 Explain 查询中注意到您有 342627,这是您在数据库中的总记录吗?如果是,则意味着它正在执行全表扫描而不考虑索引,我只看到 2 个“条件”和“临时”。
关于mySQL 运行查询真的很慢 - 60 秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26516506/