Mysql 查询带有 order by。奇怪的执行计划

标签 mysql explain

我有 3 张 table :

Product (about 700000 rows)
ProductId int(11) AI PK 
ManufacturerId int(11) FK
Name varchar(256) 
Description text 
SKU varchar(64) 
Code varchar(64) 
ArtId int(11) 
StockStateId int(2) FK
Quantity int(11) 
QuantityText varchar(61) 
Price decimal(12,2) 
CurrencyId int(2) 
AutoImport bit(1) 
ImpactOnBalance bit(1) 
HasPhoto bit(1) 
HasParams bit(1)

StockState (3 rows)
StockStateId int(2) AI PK 
Name varchar(64)

Manufacturer (about 200 rows)
ManufacturerId int(11) AI PK 
Name varchar(64) 
Description text 
SortOrder int(11)

这是我的查询

select
     p.ProductId
    ,p.Name
    ,p.Quantity
    ,p.QuantityText
    ,m.ManufacturerId
    ,m.Name as ManufacturerName
    ,ss.StockStateId
    ,ss.Name as StockStateName
from Product p
inner join Manufacturer m on m.ManufacturerId = p.ManufacturerId
inner join StockState ss on ss.StockStateId = p.StockStateId
order by p.ProductId asc
limit 1000, 25

我不明白为什么 mysql 不使用正确的索引(大约需要 10 秒才能得到结果)。执行计划看起来像这样 first query 。 我可以强制mysql使用主索引

from Product p force index (primary)

它将性能提高到 0.015 秒,但我将在 SP 中使用此查询,其中顺序取决于输入参数。所以我添加了虚拟案例条件

set @order = '';
select
     p.ProductId
    ,p.Name
    ,p.Quantity
    ,p.QuantityText
    ,m.ManufacturerId
    ,m.Name as ManufacturerName
    ,ss.StockStateId
    ,ss.Name as StockStateName
    from Product p force index (primary)
inner join Manufacturer m on m.ManufacturerId = p.ManufacturerId
inner join StockState ss on ss.StockStateId = p.StockStateId
order by case when @order = '' then p.ProductId end asc
limit 1000, 25

此查询应该具有与前一个查询相同的执行计划(按 PK 的同一列排序),但不,我有文件排序。 third query

这是为什么呢?有人可以帮我解决这个问题吗? (提高查询性能)r

最佳答案

我认为你应该尝试这个,有一个左连接概念等等。

set @order = '';
select
     p.ProductId
    ,p.Name
    ,p.Quantity
    ,p.QuantityText
    ,m.ManufacturerId
    ,m.Name as ManufacturerName
    ,ss.StockStateId
    ,ss.Name as StockStateName
    from Product p force index (primary)
//this line what I mean 
inner join Manufacturer m on p.ManufacturerId = m.ManufacturerId
//also this line what I mean
inner join StockState ss on p.StockStateId = ss.StockStateId
order by case when @order = '' then p.ProductId end asc
limit 1000, 25

因为您必须先检查产品中的行,然后加入制造商

如果先检查Manufacturer,如果Product中不存在Manufacturer中的行就会出现问题(浪费时间)

关于Mysql 查询带有 order by。奇怪的执行计划,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34571798/

相关文章:

sql - 如何使用 DB2 Explain?

Postgresql EXPLAIN 命令

mysql - 用于多容器 Docker 配置的 AWS Elastic beanstalk 中的版本错误

php - 如果用户正确输入电子邮件,我该如何正确显示错误并继续?

mysql - 在 MySQL 中计算频率

java - 在 Android 中将 Php 连接到 MySQLi

mongodb - 为什么 MongoDB 不能使用与查询非常相似(不完全)的复合索引?

mysql - 如何使用具有索引键的 IN 优化 SQL 查询

java - 可以说服 JDBC + MySQL 忽略时区吗?