mysql用limit取数慢_mysql – LIMIT 1非常慢,对于特定的记录,使用不同的键

在 MySQL 数据库中遇到一个奇怪的现象,当针对特定 `cl_unit_id` 使用 `LIMIT 1` 进行查询时,查询速度显著变慢,而其他 `cl_unit_id` 值则能快速通过 `log_type_unit_id` 索引完成。问题出现的查询是针对 `ch_log` 表,包含 `cl_unit_id`, `cl_type`, 和 `cl_date` 等字段。查询优化显示,在慢查询中使用了 `cl_date` 索引,而在正常情况下使用 `log_type_unit_id` 索引。尝试了删除 `LIMIT 1` 或添加索引提示和 `ORDER BY` 主键等方法可以提高查询速度,但作者希望找出根本原因,而不是临时解决方案。" 103728989,9236603,Nessus安全漏洞扫描工具安装与使用教程,"['安全', '服务器', '运维']
摘要由CSDN通过智能技术生成

我正在诊断间歇性慢查询,并在MySQL中发现了一个奇怪的行为我无法解释.对于一个特定的情况,它只是选择一个不同的,非最优的关键策略,只有当做LIMIT 1时.

表(为简洁起见,删除了一些未引用的数据列)

CREATE TABLE `ch_log` (

`cl_id` BIGINT(20) NOT NULL AUTO_INCREMENT,

`cl_unit_id` INT(11) NOT NULL DEFAULT '0',

`cl_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',

`cl_type` CHAR(1) NOT NULL DEFAULT '',

`cl_data` TEXT NOT NULL,

`cl_event` VARCHAR(255) NULL DEFAULT NULL,

`cl_timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

`cl_record_status` CHAR(1) NOT NULL DEFAULT 'a',

PRIMARY KEY (`cl_id`),

INDEX `cl_type` (`cl_type`),

INDEX `cl_date` (`cl_date`),

INDEX `cl_event` (`cl_event`),

INDEX `cl_unit_id` (`cl_unit_id`),

INDEX `log_type_unit_id` (`cl_unit_id`, `cl_type`),

INDEX `unique_user` (`cl_user_number`, `cl_unit_id`)

)

ENGINE=InnoDB

AUTO_INCREMENT=419582094;

这是查询,对于一个特定的cl_unit_id,这个查询运行速度很慢:

EXPLAIN

SELECT *

FROM `ch_log`

WHERE `ch_log_type` ='I' and ch_log_event = 'G'

AND cl_unit_id=1234

ORDER BY cl_date DESC

LIMIT 1;

id|select_type|table |type |possible_keys |key |key_len|ref|rows|Extra

1 |SIMPLE |ch_log|index|cl_type,cl_event,cl_unit_id,log_type_unit_id|cl_date|8 |\N |5295|Using where

对于cl_unit_id的所有其他值,它使用的速度快得多的log_type_unit_id键.

id|select_type|table |type|possible_keys |key |key_len|ref |rows|Extra

1 |SIMPLE |ch_log|ref |ch_log_type,ch_log_event,ch_log_unit_id,log_type_unit_id|log_type_unit_id|5 |const,const|3804|Using where; Using filesort

>所有查询大约需要0.01秒.

>“慢单位”查询需要10-15分钟!

对于这个“单位”的数据,我看不出任何奇怪的东西:

单位1234只有I和事件G的6个记录.

>其他单位还有更多.

>单位1234只有32,000日志是典型的.

>数据本身是正常的,没有更大或更大.

>数据库中有大约3000个“单位”,表示设备记录的东西. cl_unit_id是它们唯一的PK(尽管没有约束).

基本信息

>总共有30万条记录,约12GB

> mysql 5.1.69-log

> Centos 64bit

>数据正在逐渐变化(30m = 3个月的日志),但是我不知道这是否发生过

我试过的事情,可以“解决”问题:

>删除LIMIT 1 – 查询以毫秒为单位运行并返回数据.

>更改为LIMIT 2或其他组合,例如2,3 – 以毫秒为单位运行.

>添加索引提示 – 解决它:

FROM `ch_log` USE INDEX (log_type_unit_id)

但是…我不想将这个代码硬编码到应用程序中.

>在主键上添加第二个命令也“解决”它:

ORDER BY cl_id, cl_date DESC

给出解释:

id|select_type|table |type|possible_keys |key |key_len|ref |rows|Extra

1 |SIMPLE |ch_log|ref |ch_log_type,ch_log_event,ch_log_unit_id,log_type_unit_id|log_type_unit_id|5 |const,const|6870|Using where

这与提示类型略有不同,检查的记录更多(6,000),但仍以10毫秒为单位运行.

再次,我可以做到这一点,但我不喜欢使用我不明白的副作用.

所以我觉得我的主要问题是:

a)为什么只发生在LIMIT 1?

b)数据本身如何影响关键策略呢?数据的哪个方面,看起来像索引的数量和传播似乎是典型的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值