首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >非常慢的MySQL查询,即使使用索引

非常慢的MySQL查询,即使使用索引
EN

Database Administration用户
提问于 2013-01-09 14:11:59
回答 2查看 12.6K关注 0票数 7

我有一个相对较大的4深度关系数据设置,如下所示:

client_applications:(可能有1000‘S的记录)

成型机- ...

成型机- account_id

成型机- deleted_at

client_application_versions:(可能有10,000's的记录)

成型机- ...

成型机- client_application_id

成型机- deleted_at

cloud_logs:(可能有100万S的记录)

再来.

成型机- client_application_version_id

成型机- deleted_at

logs:(可能有10亿,000,000‘S的记录)

成型机- ...

成型机- cloud_log_id

成型机- time_stamp

成型机- deleted_at

我还在开发中,所以结构和设置不是一成不变的,但我认为它是好的。使用Rails 3.2.11和InnoDB MySQL。数据库中填充了一小组数据(与最终的db大小相比) (logs只有70万行),我有4个查询(其中3个有问题)来检索日志。

  1. 抓取日志的第一页,按时间戳排序,受account_idclient_application_idclient_application_version_id的限制(超过100秒)
  2. 抓取日志的第一页,按时间戳排序,受account_idclient_application_id限制(超过100秒)
  3. 抓取日志的第一页,按时间戳排序,受account_id限制(超过100秒)
  4. 抓取日志的第一页,按时间戳排序(~2秒)

以下是解释语句。我已经对所有适用的字段建立了索引。复制...id表上的各个logs字段以防止联接是否更好?或者,当我问这些问题的时候,是不是缺少了一些神奇的酱汁?我以前从来没有处理过这么多的数据,所以也许我处理设置和查询的标准方法就是不扩展?如何更改设置或语句以使这些查询在合理的时间内返回?

更新

我在日志表上添加了几个组合索引,并在时间上稍微减少了一点。以下是解释就是为了这个。我的结论是,订单方法是延迟的原因。删除order by timestamp desc将导致查询在一秒钟左右内返回。因此,新的问题是,为什么在时间戳上建立索引时,运行这个查询还需要超过一分钟的时间?

更新2

使用子查询将100个id的性能提高到14秒,但这仍然太长了。到目前为止,我尝试过的优化都缩短了一些时间,但我觉得它们并没有从根本上解决问题。用于子查询方法的这是解释

EN

回答 2

Database Administration用户

发布于 2013-01-11 17:38:44

这里不是DBA或MySQL专家,但让我们试试:)。因此,让我们使用您的第二个查询--比第一个查询小一点--并简化表名。

我们有如下内容:(LO =LO,CL = cloud_logs,CAV = client_application_versions,CA = client_applications)

代码语言:javascript
运行
复制
 SELECT LO.* FROM LO 
 INNER JOIN CL      ON CL.id    = LO.cloud_log_id 
 INNER JOIN CAV     ON CAV.id   = CL.client_application_version_id 
 INNER JOIN CA      ON CA.id    = CAV.client_application_id 
 WHERE (LO.deleted_at IS NULL) 
 AND (CA.account_id = '3') 
 AND (CA.id = '5') 
 ORDER BY timestamp DESC LIMIT 100 OFFSET 0

所以你说大约需要100秒钟,对吧?

当你说:

我已经对所有适用的字段建立了索引。

但我相信这就是缺陷所在。你没有那么多的连接,你可能有70亿个数据,或者仅仅700个,如果索引被正确地考虑的话,这应该是很好的表现,我认为这可能是因为索引不好而影响性能的顺序/限制。

1你试过:

代码语言:javascript
运行
复制
SELECT LO.* FROM LO WHERE (LO.deleted_at IS NULL)

代码语言:javascript
运行
复制
SELECT * FROM CA WHERE (CA.account_id = '3') AND (CA.id = '5')

看看这些请求是如何及时执行的,如果这两个表一切正常的话?

[2]你也有索引时间戳吗?索引您正在进行的"order“列也是至关重要的。实际上,您甚至应该考虑您的数据以及您要查询的每个数据有多少值。这里很好地解释了这一点:http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/,肯定会对您有所帮助。

3.根据我几分钟前在MySQL上所读到的内容,您也可以尝试MySQLCheck,看看您的表中的所有内容是否都还好,如果您认为索引是ok的,http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html。我知道,在早期版本的甲骨文中,我们必须在创建索引之后计算统计数据,也许这里类似的东西?

希望这能有所帮助。

编辑: 12/01/13在评论后

好吧,很高兴看到你已经把时间除以4,但事实上25s太长了。

[1]您是否尝试过通过创建一个有意义的索引来处理索引,如Peter (http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/)所解释的那样?比如索引(CA.account_id,CA.id,时间戳)等等?

[2]当您按/限制按以下方式处理订单时,需要多长时间?

代码语言:javascript
运行
复制
SELECT LO.* FROM LO 
 INNER JOIN CL      ON CL.id    = LO.cloud_log_id 
 INNER JOIN CAV     ON CAV.id   = CL.client_application_version_id 
 INNER JOIN CA      ON CA.id    = CAV.client_application_id 
 WHERE (LO.deleted_at IS NULL) 
 AND (CA.account_id = '3') 
 AND (CA.id = '5') 

检查这是否是按/限制影响您的性能的订单?

3/在第2种情况下,您可以尝试这样的方法:

代码语言:javascript
运行
复制
SELECT LO.* FROM LO 
 INNER JOIN CL      ON CL.id    = LO.cloud_log_id 
 INNER JOIN CAV     ON CAV.id   = CL.client_application_version_id 
 INNER JOIN CA      ON CA.id    = CAV.client_application_id 
 INNER JOIN 
 (
    SELECT LO.id FROM LO 
    INNER JOIN CL      ON CL.id    = LO.cloud_log_id 
    INNER JOIN CAV     ON CAV.id   = CL.client_application_version_id 
    INNER JOIN CA      ON CA.id    = CAV.client_application_id 
    WHERE (LO.deleted_at IS NULL) 
    AND (CA.account_id = '3') 
    AND (CA.id = '5') 
    ORDER BY timestamp DESC LIMIT 0,100
  ) AS PERF  ON PERF.id = LO.id

将LO.id替换为用日志表示的列(我想您有某种日志id )。这是基于:http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/注释,您可以更改限制0,100并保留偏移量关键字,以防止需要它(如果需要PostgreSQL兼容性的话)。

票数 2
EN

Database Administration用户

发布于 2019-10-08 10:02:57

不确定这个帮助,但在我的例子中,有带有3mil行的表。非常简单的连接或联合或循环查询都非常慢。仅对20行结果进行测试和测试,我只需输入一个简单的命令来查询

力指数(one_colum_indexed)

如果您的表中有多个索引字段,那么您必须逐个测试哪个one_colum_indexed,以查找哪一个是最好的。

所有的信用都在这里,使用强制索引加快查询速度

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/31636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档