按ID排序的复合索引的并发查询速度极慢

时间:2018-05-07 03:45:19

标签: mysql sql concurrency sql-order-by composite-index

我的表格定义如下:

| book | CREATE TABLE `book` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `provider_id` int(10) unsigned DEFAULT '0',
  `source_id` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  `title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `description` longtext COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`),
  UNIQUE KEY `provider` (`provider_id`,`source_id`),
  KEY `idx_source_id` (`source_id`),
) ENGINE=InnoDB AUTO_INCREMENT=1605425 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

当有大约10个并发读取时使用以下sql:

SELECT * FROM `book`  WHERE (provider_id = '1' AND source_id = '1037122800') ORDER BY `book`.`id` ASC LIMIT 1  

它变慢,大约需要100毫秒。

但是,如果我将其更改为

SELECT * FROM `book`  WHERE (provider_id = '1' AND source_id = '221630001') LIMIT 1  

那么这是正常的,需要几毫秒。

我不明白为什么按ID添加订单会使查询慢得多?任何人都可以说出来吗?

2 个答案:

答案 0 :(得分:0)

尝试添加所需的列(选择列名,..)而不是*或参考。

  

Why is my SQL Server ORDER BY slow despite the ordered column being indexed?

答案 1 :(得分:0)

我不是mysql专家,也无法执行详细分析,但我的猜测是,因为您在UNIQUE KEY子句中为WHERE提供了值,引擎可以使用索引直接获取该行。

但是,当您向ORDER BY idPRIMARY KEY询问时,会更改访问路径。引擎现在猜测,因为它有id上的索引,并且您想按id排序,最好以PK顺序获取该数据,这将避免排序。但在这种情况下,它会导致较慢的结果,因为它必须将每一行与标准进行比较(表扫描)。

请注意,这只是猜想。您需要EXPLAIN两个语句来查看正在发生的事情。