依赖查询的EC(内部)计算

时间:2016-08-22 20:02:46

标签: mysql sql-server query-optimization

我目前正在研究查询优化,我正在尝试计算其中包含依赖查询的查询的成本。

查询是:

select 
    U.userName, email, yearOfBirth, countryName
from 
    tblUser U 
inner join 
    tblCountry C on U.countryNo = C.countryNo
left join 
    tblList L on U.userName = L.userName
where 
    noOfPoints = 1000 
    and yearOfBirth = 1975 
    and listNo is null 
    and not exists (select count(*)
                    from tblseek S
                    where S.userName = U.userName
                    having count(serialNo) > 3)

现在有些数据:

首先是表格及其连接:

enter image description here

tblCountry:Nr = 19,Fr = 67且Br = 1

tblUser:Nr = 1,881,923,Fr = 11,Br = 171,084

tblList:Nr = 4,667,166,Fr = 62,Br = 75,277

tblSeek:Nr = 8,530,865,Fr = 13,Br = 656,221

用户之间的分配就宝藏的查找量而言:

0查找:10%的用户

1次查询:11%的用户

2次查询:19%的用户

3及以上:60%的用户

就每个用户的列表数量而言,用户之间的分配是:

0列表:30%的用户

1-3列表:34%的用户

4-6列出:36%的用户

众所周知,所有系统中的最大点数为5200,并且在用户之间均匀分布。

据了解,年龄最大的用户年龄为16岁,年龄最大的是57岁,所有用户的年龄均匀分布。

  • 块大小为:2048位

  • 为查询分配的内存量为:100块

  • 每个表都按主键排序,如果有多个字段,则按照表中的外观顺序排序。

现在,我想要计算的是什么:

我试图在外部查询中进行连接之前确定运行依赖查询的成本,因此将tblUser加载到内存并执行内部查询,然后完成其他连接。

我的问题:我发现为了做到这一点,我需要以171,084个块为代价将tblUser加载到内存中,并且还需要以656,221个块为代价加载tblSeek,我无法确定是如何以及在何处执行" Where"因为您可能会注意到该子句中的大多数条件都与tblUser的属性有关(除了列表条件)。

我设法得出一个估计(我不确定这是正确的,请纠正我,如果我错了)有多少记录会回答" points = 1000"在统一的转移知识(其361条记录)下,并且也与#34; yearOfBirth = 1975"(45,900条记录)相同。我是通过将tblUser的Nr分别与均匀转移已知的数字区域分开来实现的。

我怎么能想出一种方法将它们组合成一个数字,显示有多少记录会在所有条件混合在一起(包括依赖查询)。

如果你能引导我一点,我将非常感激。

谢谢,

汤姆

1 个答案:

答案 0 :(得分:0)

使用EXPLAIN FORMAT=JSON SELECT ...进一步了解查询的执行方式。

使用它来获得努力的一些“行数”:

FLUSH STATUS;
SELECT ...
SHOW SESSIONS STATUS LIKE 'Handler%';

指标的影响。 (我不知道你已经拥有什么,因为你没有提供SHOW CREATE TABLE。)

U: INDEX(yearOfBirth, noOfPoints)

EXISTS(...)通常简称为EXISTS ( SELECT * FROM ... );不需要COUNT(*)。我不明白EXISTS的目的。也许这会检查tblseek中的行数:

AND ( SELECT COUNT(*) FROM tblseek WHERE userName = U.userName ) <= 3

您可能希望INDEX(userName, serialNo)按此顺序。这是一个“覆盖”索引,以便子查询可以完全在索引中执行。 EXPLAIN将通过“使用索引”来表示。

该子查询总共将触及tblseek(或其索引)中的每一行。实际上,每次扫描都会超过一次。因此,触摸的行数可能是N + M,其中N是tblseek中的行数,M是userNametblseek的不同值的数量。如果没有该索引,行数将会高很多。