Mysql 通过Join Where Group by select查询更正索引,避免使用临时查询;使用文件排序

Mysql 通过Join Where Group by select查询更正索引,避免使用临时查询;使用文件排序,mysql,join,group-by,Mysql,Join,Group By,我已经搜索了很多关于下面描述的案例的解决方案,但不幸的是,我没有找到类似的案例 我有以下情况: (作为新用户,网站拒绝了我的图片,但我可以通过邮件发送。下面是它的文本表示) 我必须显示一些性能指标(“表2”单元格中的“计数器”)、随时间聚合(“表2”单元格中的“时间”)和集群(“表1”交换计划中的“集群名称”) 连接是通过两个表“SiteID”的公共列完成的。请注意,在表2中的“单元格”中,每个SiteID由3个不同的对象(“单元格”)组成。事实上,我为每个单元格计算“Counter”的和 查询

我已经搜索了很多关于下面描述的案例的解决方案,但不幸的是,我没有找到类似的案例

我有以下情况: (作为新用户,网站拒绝了我的图片,但我可以通过邮件发送。下面是它的文本表示)

我必须显示一些性能指标(“表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)