MySQL慢速连接-但不总是,也不是所有表上都有
我们遇到了一个MySQL数据库的性能问题,这太奇怪了,我们需要另一组眼睛来告诉我们是否疯了。 我们团队中有2名通过MySQL认证的开发人员,但他们只能说:“这是不可能的” 无论如何,情况是这样的:我们有一个疑问,理论上应该是合理的快速,但实际上是缓慢的。如果我们通过删除1个连接来缩小查询,查询将变得非常快。如果我们删除一个不同的联接,它仍然非常慢,尽管联接表的结构几乎相同。更糟糕的是:连接有时是快速的,有时不是。。。这似乎是某种随机问题,尽管它与服务器负载无关,因为我在本地系统上也有它 表结构如下所示:MySQL慢速连接-但不总是,也不是所有表上都有,mysql,join,performance,indexing,Mysql,Join,Performance,Indexing,我们遇到了一个MySQL数据库的性能问题,这太奇怪了,我们需要另一组眼睛来告诉我们是否疯了。 我们团队中有2名通过MySQL认证的开发人员,但他们只能说:“这是不可能的” 无论如何,情况是这样的:我们有一个疑问,理论上应该是合理的快速,但实际上是缓慢的。如果我们通过删除1个连接来缩小查询,查询将变得非常快。如果我们删除一个不同的联接,它仍然非常慢,尽管联接表的结构几乎相同。更糟糕的是:连接有时是快速的,有时不是。。。这似乎是某种随机问题,尽管它与服务器负载无关,因为我在本地系统上也有它 表结构如
Table : article Rows : 57491
Field Type Null Key Default Extra
arti_id int(10) unsigned NO PRI auto_increment
prev_id int(10) unsigned YES MUL (null)
news_id int(10) unsigned NO MUL (null)
cate_id int(10) unsigned NO MUL (null)
pdf_id int(10) unsigned YES MUL (null)
imag_id int(10) unsigned YES MUL (null)
publication_date date NO MUL (null)
title varchar(255) NO MUL (null)
full_text text YES (null) (null)
Table : category Rows : 3
Field Type Null Key Default Extra
cate_id int(10) unsigned NO PRI auto_increment
code varchar(7) NO (null) (null)
Table : language Rows : 4
Field Type Null Key Default Extra
lang_id int(10) unsigned NO PRI auto_increment
code varchar(2) NO (null) (null)
Table : newspaper Rows : 393
Field Type Null Key Default Extra
news_id int(10) unsigned NO PRI auto_increment
lang_id int(10) unsigned NO MUL (null)
name varchar(255) NO UNI (null)
现在出现了奇怪的部分:正如你所看到的046_报纸和046_分类都有一个主键(幸运的是)。它们都被外键引用自a046_文章。当我们运行以下查询时:
SELECT SQL_NO_CACHE
article.*
FROM
article
INNER JOIN
newspaper AS `n`
ON
article.news_id = n.news_id
ORDER BY
article.publication_date DESC
LIMIT
50
我们在0.016秒后得到一个结果,这非常快
现在,当我们将join with Paper替换为join with category时:
SELECT SQL_NO_CACHE
article.*
FROM
article
INNER JOIN
category AS `c`
ON
article.cate_id = c.cate_id
ORDER BY
article.publication_date DESC
LIMIT
50
查询耗时1.02秒
奇怪的是,情况并非总是如此。有时,没有明显的原因,第一个查询也需要那么长的时间
最后,我们要做的是:
SELECT SQL_CALC_FOUND_ROWS
*,
`n`.`name` AS `news_name`,
`c`.`cate_id`,
`c`.`code` AS `cate_name`,
`l`.`code` AS `lang_name`
FROM
`article`
INNER JOIN
`newspaper` AS `n`
ON
article.news_id = n.news_id
INNER JOIN
`category` AS `c`
ON
article.cate_id = c.cate_id
INNER JOIN
`language` AS `l`
ON
n.lang_id = l.lang_id
ORDER BY
`article`.`publication_date` DESC
LIMIT
50
在这一点上需要超过12秒。部分原因是*,我们可以用单个字段替换*,但仍然需要3秒钟
我们已经尝试了很多方法:
-添加索引(尽管所有必需的索引都已经存在,添加更多的索引只是一个坏主意)
-增加排序缓冲区大小和键缓冲区
-看着我解释了很多。。。
-反复阅读MySQL手册
-阅读了很多论坛
然而,这样做并没有解决这个问题
如果有任何人有任何想法,请随时高呼!如果您需要SQL脚本,甚至需要访问数据库,那么您可以尝试一下,让我知道。。。我们的客户抱怨了很多关于慢页面的问题
谢谢
我将对所有表在表上显示索引,并检查基数列是否正确(即没有空值)。或者,您可以对每个表进行分析,以获得更好的度量。由于您有2名经过认证的MySQL开发人员,您可能已经这样做了
下一步是查看解释,看看MySQL是如何优化它的。您可能需要使用强制、使用或忽略以使其正确优化。由于MySQL和具有缓存数据(即索引)的操作系统不同,速度也会有所不同,但当您指定“无缓存”时,查询的速度则不同。您可以发布解释吗?我想您可以尝试使用标量查询。如果查询优化器被愚弄了,可能会出现问题。奇怪的是,它是随机发生的。。。看一看直线连接;这允许您避免查询优化器重新排列它们。我们遇到了相同的问题,这里不再允许连接。我们通过修改查询而不是join来解决这个问题,我们使用select*from table1,table2,其中table1.field=table2.field。人们会告诉你,对你的问题,两个查询的EXPLAIN的性能和输出都不一样,但没有区别。@Grumpy:我也很难相信这一点。你有没有任何测试案例可以证明这一点?@Grumpy:我更改了两个查询,每个查询都有几个连接,并且删除了连接,EXPLAIN给出的结果没有任何变化。我相信您的改进来自其他地方,我不认为这是一条通向优化的道路,相反,它可能导致更难阅读的代码。