性能改进:左外连接、排序依据、子查询:主查询未拾取索引

Posted

技术标签:

【中文标题】性能改进:左外连接、排序依据、子查询:主查询未拾取索引【英文标题】:performance improvement: Left outer Join, Order By, Subquery: Index not picked up by the main query 【发布时间】:2012-01-06 04:53:41 【问题描述】:

表1:

pk1 pk2 pk3 field1 field2 修改日期版本

表 2:

pk1 pk3 tab1 tab2 tab3

(pk1,pk2)-table1 的主键 (pk1,pk3)-table2的主键

pk1,pk3 -外键

示例查询是这样的:

select *.tab1, tab2.field1
from table1 tab1
LEFT JOIN table2 tab2
ON (tab1.pk1 =tab2.pk1 AND tab1.pk3 = tab2.pk3)
WHERE (tab1.pk1= 'xx' OR tab1.pk1 = 'yy')
AND (tab1.pk3 = 'aa' OR tab1.pk3 is null)
AND (tab1.modifieddate >'somevalue' OR (tab1.modifieddate = 'somevalue' AND tab1.pk2 >    ' \n') )
AND tab1.field1 = (select max(field1) from table1
where ((tab1.pk1= 'xx' OR tab1.pk1 = 'yy') 
AND (tab1.pk3 = 'aa' OR tab1.pk3 is null) AND field3 = tab1.field3))
ORDER BY modifieddate desc,pk1 desc
limit 0,50

创建的索引是:

index1(pk1,pk3,修改日期,pk2,field3)

index2(pk1,修改日期,pk2,field3)

外键索引(pk1,pk3)

子查询索引(pk1,pk3,field2)

经过分析,发现在外层查询中使用OR是不占用索引的原因。 http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html-->斯蒂芬·杜威的最后评论。

我浏览了许多 *** 帖子并尝试使用 UNION ALL。在那种情况下,对于我的场景,我最终得到了一个派生表。可以使派生表使用索引吗?


编辑 解释计划:

id select-type          table   type        possible_keys             key       key-len   ref          rows     extra
1   primary             tab1    range       primary,index1,index2      pk3       497      null           734     using where;using filesort
2   primary             tab2    ref         primary,forignkeyindex,pk3 pk3       110   db.tab1.pk3         1       
3   dependent subquery  table1  ref_or_null pk3,subqueryindex     subqueryindex  497  tab1.pk3,tab1.field1 2     using where

您能否就优化此查询提供一些帮助? :)

【问题讨论】:

当我将 (tab1.pk3 = 'aa' OR tab1.pk3 is null) 更改为 (tab2.pk3 = 'aa' OR tab2.pk3 is null),在解释计划中,我发现using filesort; 最后一列缺失。它会提高性能吗? 【参考方案1】:

您使用

加入
tab1.pk1 =tab2.pk1 AND tab1.pk3 = tab2.pk3)

尝试使用您用于加入的键创建索引,即

table1: index1(pk1,pk3)
table2: index2(pk1,pk3)

【讨论】:

以上是关于性能改进:左外连接、排序依据、子查询:主查询未拾取索引的主要内容,如果未能解决你的问题,请参考以下文章

MySQL高级第八篇:关联查询子查询和排序相关优化

与子查询相比,为啥左外连接查询给出不同的结果?

带有子查询的左外连接?

使用 LINQ 查询语法 EF Core C# 的左外连接

netezza 左外连接查询性能

分页结果集中的选择子查询或左外连接哪个更快