Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL在主键上强制过滤使查询速度更快_Mysql_Sql - Fatal编程技术网

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。连接可能会干扰优化。