在mysql中使用元组比较是否有效?

dop*_*dop 9 mysql tuples sqlperformance

我有一张书桌:

CREATE TABLE `books` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `nameOfBook` VARCHAR(32),
    `releaseDate` DATETIME NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    INDEX `Index 2` (`releaseDate`, `id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
Run Code Online (Sandbox Code Playgroud)

AUTO_INCREMENT = 33029692;

我将两个SQL请求与releaseDate上的sort进行了比较.这两个请求都返回相同的结果.

(简单的一个)

select SQL_NO_CACHE  id,name, releaseDate  
from books  
where releaseDate <= '2016-11-07'  
AND (releaseDate<'2016-11-07' OR id <    3338191)  
ORDER  by releaseDate DESC, id DESC limit 50;
Run Code Online (Sandbox Code Playgroud)

(元组比较或行比较)

select SQL_NO_CACHE  id,name, releaseDate 
from books 
where (releaseDate ,id) < ('2016-11-07',3338191) 
ORDER  by releaseDate DESC, id DESC limit 50;
Run Code Online (Sandbox Code Playgroud)

当我解释请求时,我得到了这个

简单的一个:

"id";"select_type";"table";"type";"possible_keys";"key";"key_len";"ref";"rows";"Extra"
"1";"SIMPLE";"books";"range";"PRIMARY,Index 2";"Index 2";"9";"";"1015876";"Using where; Using index"
Run Code Online (Sandbox Code Playgroud)

我们可以看到它正在解析行的"1015876"

元组比较的解释:

"id";"select_type";"table";"type";"possible_keys";"key";"key_len";"ref";"rows";"Extra"
"1";"SIMPLE";"books";"index";"";"Index 2";"13";"";"50";"Using where; Using index"
Run Code Online (Sandbox Code Playgroud)

我们可以看到它正在解析"50"行.

但是,如果我检查了exectution时间,那么简单的一个:

* Affected rows: 0  Lignes trouvées: 50  Avertissements: 0  Durée pour 1 query: 0,031 sec. */
Run Code Online (Sandbox Code Playgroud)

和元组一:

/* Affected rows: 0  Lignes trouvées: 50  Avertissements: 0  Durée pour 1 query: 3,682 sec. */
Run Code Online (Sandbox Code Playgroud)

我不明白为什么根据解释,元组比较更好但执行时间差得多?

Ric*_*mes 12

多年来我一直对此感到恼火. WHERE (a,b) > (1,2)从未被优化过,尽管它很容易转化为另一种配方.直到几年前,甚至其他格式也未得到很好的优化.

使用EXPLAIN FORMAT=JSON SELECT ...可能会给你一些更好的线索.

同时,EXPLAIN忽略LIMIT并建议1015876.在许多情况下,EXPLAIN提供"体面"行估计,但不是这些中的任何一个.

随意提交错误报告:http://bugs.mysql.com(并在此处发布链接).

尽管OR历史上不可优化,但最近对另一种配方进行了优化.

where  releaseDate <  '2016-11-07'  
   OR (releaseDate  = '2016-11-07' AND id < 3338191)  
Run Code Online (Sandbox Code Playgroud)

为了测量查询优化,我喜欢这样做:

FLUSH STATUS;
SELECT ...
SHOW SESSION STATUS LIKE 'Handler%';
Run Code Online (Sandbox Code Playgroud)

小的值,例如"50",表示良好的优化; 大值(1M)表示扫描.处理程序编号是准确的; 不像估计EXPLAIN.

更新 5.7.3改进了元组的处理,又称"行构造函数"