繁体   English   中英

MySQL慢查询-使用Filesort

[英]MySQL Slow Query - Using Filesort

我正在尝试在我的MySQL数据库上运行一个查询,该查询需要70秒钟以上的时间才能运行,而我对于为什么不使用索引的问题scratch之以鼻。

这是查询:

SELECT PriceId, InstrumentId, Date, Open, High, Low, Close, Volume, UnadjustedClose
FROM price
ORDER BY InstrumentId, Date DESC

价格表具有一个带有InstrumentId,Date的索引(以及其他索引)。 该表本身有8000万行,由2个整数,一个日期,一个长整数和5个小数组成。

说明命令的类型为ALL,对于可能的键,键和引用,类型为Null,并告诉我系统正在使用文件排序。

这是我从系统中得到的最好的吗? 我希望索引可以用来使排序更快。

添加:

这是表的定义:

PriceId int PK, NN, AI
InstrumentId int NN
Date Date NN
Open Decimal(12,4)
High Decimal(12,4)
Low Decimal(12,4)
Close Decimal(12,4)
UnadjustedClose Decimal(12,4)
Volume BigInt

Indexes:

Primary -> PriceId
IX_InstrumentId -> InstrumentId
IX_Date -> Date
IX_InstrumentDate -> InstrumentId, Date

解释输出为:

id: 1
select_type: Simple
table: price
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 77926335
Extra: using filesort

优化器将不使用索引,因为您正在检索所有行,并且索引不包含您尝试获取的所有列。 这意味着该索引不是覆盖索引。

在大多数情况下,使用索引和基于索引的记录查找来检索额外的列要比扫描整个表(当您检索所有内容时)效率低。

您有一些选择:

  • 在索引中包括所有必需的列:这需要更多空间并减慢写操作的速度。
  • 根据索引的第一列向查询添加过滤器。 如果筛选器具有足够的选择性(将所需的行数缩减到合理的水平),则服务器将使用您的索引。
  • 将数据过滤到合理大小
  • 在应用程序中进行排序
  • 将主键(群集)修改为(InstrumentID ASC, Date DESC)

编辑关于最后一个选项的更多信息

您的表看起来像一个日志表。 在日志表中,向每个记录添加唯一的整数ID以消除重复似乎是一个好习惯(但在大多数情况下不是这样)。 但是,在大多数情况下,您不使用该ID。 在MySQL中,主键也是集群键(这意味着数据将在磁盘上以该顺序排序-或多或少,现在可以原谅碎片。)

在日志表中,最好使用记录的实体的ID和时间戳(在您的情况下为InstrumentID,Date)作为聚簇索引(MySQL中的主键)。 当您这样做时,数据的顺序将适合常见的业务需求,这意味着查询性能会更好。

如果InstrumentID和Date是唯一的(我认为应该是这样,那么一个工具不能同时具有多个价格,并且在不到一秒钟的时间内更改价格确实很少),那么复合索引可能会更好。 (并且比自动生成的整数值增加了更好的分区表的选项)。

旁注:如果您按日期进行过滤或排序的频率高于按仪器ID进行的频率,则可以更改PK中列的顺序。

编辑结束

您应该回答一些问题,以找到实现目标的更好方法:

  • 为什么需要从表中检索所有80M条记录?
  • 您的应用程序真的使用所有这些吗?
  • 如果是,是否可以在应用程序级别而不是数据库级别进行排序?
  • 记录的顺序真的很重要吗?

由于行数太多,因此无法加快速度。 从该查询创建一个Materialized View ,一旦创建,访问将更快。

MySQL不支持Materialized View ,因此您可以使用此处的教程自己实现它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM