Mysql 通过Join Where Group by select查询更正索引,避免使用临时查询;使用文件排序
我已经搜索了很多关于下面描述的案例的解决方案,但不幸的是,我没有找到类似的案例 我有以下情况: (作为新用户,网站拒绝了我的图片,但我可以通过邮件发送。下面是它的文本表示) 我必须显示一些性能指标(“表2”单元格中的“计数器”)、随时间聚合(“表2”单元格中的“时间”)和集群(“表1”交换计划中的“集群名称”) 连接是通过两个表“SiteID”的公共列完成的。请注意,在表2中的“单元格”中,每个SiteID由3个不同的对象(“单元格”)组成。事实上,我为每个单元格计算“Counter”的和 查询如下:Mysql 通过Join Where Group by select查询更正索引,避免使用临时查询;使用文件排序,mysql,join,group-by,Mysql,Join,Group By,我已经搜索了很多关于下面描述的案例的解决方案,但不幸的是,我没有找到类似的案例 我有以下情况: (作为新用户,网站拒绝了我的图片,但我可以通过邮件发送。下面是它的文本表示) 我必须显示一些性能指标(“表2”单元格中的“计数器”)、随时间聚合(“表2”单元格中的“时间”)和集群(“表1”交换计划中的“集群名称”) 连接是通过两个表“SiteID”的公共列完成的。请注意,在表2中的“单元格”中,每个SiteID由3个不同的对象(“单元格”)组成。事实上,我为每个单元格计算“Counter”的和 查询
SELECT ClusterName,Time,SUM(counter)
FROM cell
INNER JOIN swap_plan ON swap_plan.Siteid = cell.Siteid
WHERE ClusterName='Cluster A' AND Time>=day1 AND Time<=day2
GROUP BY Time
table type key key_len ref rows Extra
swap_plan ref Index 1 30 const 31 Using where; Using index; Using temporary; Using filesort
cell ref Index_siteid 13 swap_plan.SiteID 368 Using where
使用的索引如下:
SELECT ClusterName,Time,SUM(counter)
FROM cell
INNER JOIN swap_plan ON swap_plan.Siteid = cell.Siteid
WHERE ClusterName='Cluster A' AND Time>=day1 AND Time<=day2
GROUP BY Time
table type key key_len ref rows Extra
swap_plan ref Index 1 30 const 31 Using where; Using index; Using temporary; Using filesort
cell ref Index_siteid 13 swap_plan.SiteID 368 Using where
交换计划:索引1(1.ClusterName和2.SiteID)
单元格:索引\站点ID(站点ID)
优化器看起来的行数很低,这很好:
交换单元计划:6066个单元中的31个,6.6 mil单元中的368个
我的问题是“使用临时;使用文件排序”。据我所知,这来自Group By所需的排序(如果我将其删除,则不会根据Explain执行这些过程)。我发现为了避免它们,你需要在你分组依据的列上有一个索引。我有一个只包含“Time”列的特殊索引,但这个索引并没有被使用,即使有一个提示“useindexforgroupby()”
因此,我的查询运行速度不够快——大约需要15秒(比如说15个站点ID和10个日期),我需要将这段时间缩短到至少一半
我的主要问题是:
- 完全可以删除“使用临时;使用文件排序”或 减少执行所需的时间?(我试图增加 读取缓冲区大小为16MB,不起作用)
- 在连接情况下,当WHERE子句在不同的表中按2列过滤,ON子句在第3列过滤时,我需要什么样的索引定义
- 我可以应用什么样的分组优化(索引等)
提前非常感谢 我会这样写查询:
SELECT c.time
, SUM(c.counter)
, MAX(p.clustername) AS clustername
FROM cell c
JOIN swap_plan p
ON p.siteid = c.siteid
AND p.clustername = 'Cluster A'
WHERE c.time >= 'day1'
AND c.time <= 'day2'
GROUP
BY c.time
根据列的大小,覆盖索引可能会提供最佳性能。覆盖索引包括查询中引用的表中的所有列,因此可以完全从索引页满足查询,而无需查找基础表中的页
... ON cell (time, siteid, counter)
对于swap\u计划
上的索引,我将有一个以site\u id
为前导列的索引,包括clustername
列,可以是:
... ON swap_plan (clustername, site_id)
或
看起来这两列的组合很可能会有一个唯一的约束,即对于给定的clustername
,site\u id
的值将是不同的。(如果情况并非如此,并且同一个(site\u id,clustername)
元组多次出现,则可能会夸大计数器的总计
我将寻找EXPLAIN
输出,以显示从c.siteid
的值和clustername的const(字面“集群a”)值到swap\u plan
表的“ref”查找
对于大小分别为31行和368行的表,我们不会看到最佳执行计划和糟糕执行计划之间在性能(运行时间)上的显著差异
当任何一个表扩展到数百万行时,差异就会变得明显。优化器对执行计划的选择受每个表的统计信息(大小、行数、列基数)的影响,因此执行计划可能会随着表大小的增加而改变
... ON swap_plan (site_id, clustername)