Mysql查询用的顺序。奇怪的执行计划

时间:2016-01-02 23:27:46

标签: mysql explain

我有3张桌子:

<include
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        layout="@layout/app_bar_main" />


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <FrameLayout
        android:id="@+id/main_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>
</LinearLayout>

这是我的查询

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)

我无法理解为什么mysql没有使用正确的索引(得到结果需要大约10秒)。执行计划如下所示 first query。 我可以强制mysql使用主索引

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

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

from Product p force index (primary)

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

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

1 个答案:

答案 0 :(得分:0)

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

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

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

如果您首先检查制造商,如果产品中的行不存在产品(浪费时间)

,则会出现问题