MySQL在主键上强制过滤使查询速度更快
我有两张桌子,一张是点菜的,一张是点菜的。它们看起来大致像这样MySQL在主键上强制过滤使查询速度更快,mysql,sql,Mysql,Sql,我有两张桌子,一张是点菜的,一张是点菜的。它们看起来大致像这样 CREATE TABLE `Order` ( `order_id` INT NOT NULL AUTO_INCREMENT, `item_id` INT NOT NULL, `time` DATETIME NOT NULL, PRIMARY KEY (`order_id`), INDEX `combo_id` (`item_id` ASC, `order_id` DESC) VISIBLE, CONSTRAI
CREATE TABLE `Order` (
`order_id` INT NOT NULL AUTO_INCREMENT,
`item_id` INT NOT NULL,
`time` DATETIME NOT NULL,
PRIMARY KEY (`order_id`),
INDEX `combo_id` (`item_id` ASC, `order_id` DESC) VISIBLE,
CONSTRAINT `fk_order_item`
FOREIGN KEY (`item_id`)
REFERENCES `Item` (`item_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
CREATE TABLE `Item` (
`item_id` INT NOT NULL AUTO_INCREMENT,
`status` VARCHAR(1) NOT NULL,
PRIMARY KEY (`item_id`),
INDEX `status` (`status` ASC) VISIBLE);
table |type |possible_keys |key |ref |rows |filtered|extra
-------------------------------------------------------------------------------------
Order |range |PRIMARY,item_id,combo_id |PRIMARY|NULL |117003 |45.00 |Using where; Using temporary; Using filesort
Item |eq_ref |PRIMARY,status |PRIMARY|NULL |1 |52.57 |Using where;
我有一个查询,可以得到每个状态不是“D”的商品的最后5个订单
从中选择*
选择订单id、项目id、,
按Item.Item\u id在分区上排序
逐条订单\u id说明
从命
在Item.Item\u id=Order.Item\u id上加入项目
其中Item.status!='D'tmp
当tmp.0强制查询引擎使用order_id作为索引时,查询速度要快得多。只需要1秒钟。现在执行计划是这样的
CREATE TABLE `Order` (
`order_id` INT NOT NULL AUTO_INCREMENT,
`item_id` INT NOT NULL,
`time` DATETIME NOT NULL,
PRIMARY KEY (`order_id`),
INDEX `combo_id` (`item_id` ASC, `order_id` DESC) VISIBLE,
CONSTRAINT `fk_order_item`
FOREIGN KEY (`item_id`)
REFERENCES `Item` (`item_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
CREATE TABLE `Item` (
`item_id` INT NOT NULL AUTO_INCREMENT,
`status` VARCHAR(1) NOT NULL,
PRIMARY KEY (`item_id`),
INDEX `status` (`status` ASC) VISIBLE);
table |type |possible_keys |key |ref |rows |filtered|extra
-------------------------------------------------------------------------------------
Order |range |PRIMARY,item_id,combo_id |PRIMARY|NULL |117003 |45.00 |Using where; Using temporary; Using filesort
Item |eq_ref |PRIMARY,status |PRIMARY|NULL |1 |52.57 |Using where;
我真的不明白为什么这个黑客能奏效。为什么复合索引组合_id不能提高查询速度?为什么强制使用订单id会将过滤后的数字减半?有人能帮你解释一下吗?如果你用这样的短语来表达查询,它是如何工作的
select o.order_id, o.item_id, drank, i.*
from (select o.*,
rank() over (partition by o.item_id
order by order_id desc
) as seqnum
from orders o
) o join
item i
on i.item_id = o.item_id
where i.status <> 'D' and seqnum <= 5;
我认为这可以利用ordersitem\u id上的索引,order\u id作为行号。这可能有助于提高性能。因为派生表需要一个名称,所以我将其命名为tmp,并将o替换为tmp。从执行计划中,我可以看到派生表仍然有一个100.00的过滤器。然而,这个查询只需要大约1秒钟,比我的黑客查询稍微快一点。这是因为在我的查询中,联接使复合索引不再可用吗?@wendong。连接可能会干扰优化。