我有一个查询运行速度太慢,但我无法找出其背后的原因或解决方案。该查询一开始运行大约需要 22 秒,但随后我尝试删除表 Book 中的一个外键,该外键是同一个表中 ParentID 的 FK。删除此操作后,查询大约需要1 秒。这当然很好,但应该还有更多改进的空间,要么重组查询本身,要么使用不同的索引。
有人可以建议吗?为什么 Book.ParentID 的外键会导致查询时间增加如此之多?这里最好的方法是什么,尝试重写查询或查看索引?
除了将外键删除到 Book.ParentID
之外,我还尝试在所选表和一些联接上使用use index
,但没有真正的运气。
这是一个 fiddle :http://sqlfiddle.com/#!9/7f7bbb/9
但是, fiddle 中的解释计划与我在生产中得到的解释计划不同。这是生产中的解释计划(带有 Book.ParentID 的外键):
'1','SIMPLE','Bk',NULL,'index_merge','PRIMARY,fk_CategoryParent_ID_idx','PRIMARY,fk_CategoryParent_ID_idx','8,9',NULL,'2','100.00','Using union(PRIMARY,fk_CategoryParent_ID_idx); Using where; Using temporary; Using filesort'
'1','SIMPLE','CGB2',NULL,'ref','uq_ChapterGroup_Category,book_chaptergroup_unique_row_constraint,fk_Category_ChapterGroup_ID,ix_chapterGroupBook_chapterGroupID','book_chaptergroup_unique_row_constraint','9','Hypo.Bk.ID','8','100.00','Using where'
'1','SIMPLE','CCG2',NULL,'ref','uq_ChapterID_ChapterGroupItemInChapterGroup,uq_ExamID_ChapterGroupItemInChapterGroup,fk_ChapterGroup_Chapter_ID,ix_chapterChapterGroup_chapterID','fk_ChapterGroup_Chapter_ID','8','Hypo.CGB2.ChapterGroupID','2','100.00','Using where'
'1','SIMPLE','ATM',NULL,'ref','PRIMARY,fk_Chapter_AnswerTextMarker_ID,fk_QuestionGroup_AnswerTextMarker_ID','fk_Chapter_AnswerTextMarker_ID','8','Hypo.CCG2.ChapterID','5','100.00','Using where'
'1','SIMPLE','QG',NULL,'eq_ref','PRIMARY','PRIMARY','8','Hypo.ATM.QuestionGroupID','1','100.00','Using index'
'1','SIMPLE','AQS',NULL,'ref','PRIMARY,fk_AQSession_AnswerTextMarker_ID,ix_answerQuestionSession_questionSessionID','fk_AQSession_AnswerTextMarker_ID','8','Hypo.ATM.ID','313','100.00',NULL
'1','SIMPLE','QS',NULL,'eq_ref','PRIMARY,fk_QSession_User_ID,ix_QuestionSession_userId_type_sessionDate','PRIMARY','8','Hypo.AQS.QuestionSessionID','1','5.00','Using where'
我的环境中的行数:
回答问题 session 3992125
问题 session 367334
答案文本标记 9696
问题群18793
ChapterGroupItemInChapterGroup 42360
第2297章群书
书 378
最佳答案
ChapterGroupBook
看起来像一个多对多映射表。如果是这样,为什么所有列都可以为空?在适当的情况下将它们(以及其他地方的任何其他内容)设为NOT NULL
。
由于上述原因,该表没有主键
。这对 InnoDB 来说是不好的。另请参阅我的many:many tips 。
OR
是性能 killer 。有什么方法可以在 (Bk.ID=551 OR Bk.ParentID=551)
中避免这种情况吗?如有必要,请在派生表中使用 UNION
:
FROM ( ( SELECT id FROM Book WHERE id = 551 )
UNION ALL
( SELECT id FROM Book WHERE parent_id = 551 ) )
JOIN ...
(使用了“索引合并”,但可能会更慢。)
请重新格式化EXPLAIN
,以便我可以清楚地看到Rows
列。
关于mysql - MySQL 中使用连接的慢查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55489364/