MariaDB未对同一服务器上的一个数据库而非另一个数据库的相关子查询使用索引

oyjwcjzk  于 2022-11-08  发布在  其他
关注(0)|答案(1)|浏览(147)

我有一个应用程序,我注意到在从实时数据库复制到测试数据库时速度突然下降。这两个数据库都在同一个服务器上,而测试数据库是从实时数据的mysqldump创建的。所以它们是相同的,在同一个示例上。
当我解释在两个数据库上的慢速查询时,一个使用了索引,另一个没有。这种情况发生在多种查询类型上,但我将展示一个示例:
下面是我正在运行的查询:

SELECT * FROM  product
INNER JOIN product_category pc
ON product.id = pc.product_id
INNER JOIN category c
ON c.id = pc.category_id
WHERE
(c.discount_amount > 0 OR c.discount_percent > 0)
AND (c.`discount_start_date` <= NOW() OR c.`discount_start_date` IS NULL)
AND (c.`discount_end_date` >= NOW() OR c.`discount_end_date` IS NULL)

下面是来自实时数据库的解释结果:
| 标识符|选择类型(_T)|工作台|类型|可能的密钥|钥匙|密钥长度|参考文献|列|额外的|
| - -|- -|- -|- -|- -|- -|- -|- -|- -|- -|
| 一个|简单型|C语言|索引合并|PRIMARY,类别_折扣_开始_日期,类别_折扣_结束_日期,类别_折扣_金额,类别_折扣_百分比|类别_折扣_金额,类别_折扣_百分比|八、八|空值|10个|使用sort_union(类别_折扣_金额,类别_折扣_百分比);使用where|
| 一个|简单型|个人电脑|参考文献|类别标识,产品标识|类别标识|四个|棒site.c.id|十九个||
| 一个|简单型|积|eq_参考|主要|主要|四个|lollipop_site.pc.产品标识|一个||
下面是来自测试数据库的解释结果:
| 标识符|选择类型(_T)|工作台|类型|可能的密钥|钥匙|密钥长度|参考文献|列|额外的|
| - -|- -|- -|- -|- -|- -|- -|- -|- -|- -|
| 一个|简单型|积|全部|主要|空值|空值|空值|一个||
| 一个|简单型|个人电脑|全部|类别标识,产品标识|空值|空值|空值|一个|使用where;使用连接缓冲区(平面、BNL连接)|
| 一个|简单型|C语言|eq_参考|PRIMARY,类别_折扣_开始_日期,类别_折扣_结束_日期,类别_折扣_金额,类别_折扣_百分比|主要|四个|lollipop_sandbox.pc.类别标识|一个|使用where|
我使用的MariaDB里面的docker版本是10.7.3-MariaDB-1:10.7.3+玛丽亚~焦。
我希望有人能解释一下为什么服务器对不同数据库中的相同数据使用不同的查询计划。
注意这个查询以前使用的是WHERE id IN (SELECT product_id FROM...样式的查询,我按照其他stackoverflow答案的建议转换了它。这个安装有很多这样的查询也有这个问题。

ukdjmx9f

ukdjmx9f1#

有一个类似的问题,查询不使用主键,在我的情况下,在两个不同的mariadb服务器。Maridb是在完全相同的版本,也是相同的配置。下面是我的查询:

select .....
    from model_number mn
             inner join manufacturer m on (mn.manufacturer_id = m.id)
             inner join product_type pt on (mn.product_type_id = pt.id)
             inner join user cu on cu.id = mn.created_by
             inner join user uu on uu.id = mn.updated_by
             inner join replacement r on (mn.id = r.model_number_by_id)
             inner join mapping ma on r.model_number_by_id = ma.model_number_id and r.physical_item_type_id = ma.physical_item_type_id
    where r.model_number_id = 1355
      and r.physical_item_type_id = 4

索引(主键)不用于m、pt、cu和uu。
查询计划中的顺序也不同:

server using primary keys:     r,mn,uu,pt,m,cu,ma
server not using primary keys: r,m,pt,cu,uu,mn,ma

我没有胶水怎么了
以下是来自服务器的查询计划,其中所有工作都如预期:
| 标识符|选择类型(_T)|工作台|类型|可能的密钥|钥匙|密钥长度|参考文献|列|额外的|
| - -|- -|- -|- -|- -|- -|- -|- -|- -|- -|
| 一个|简单型|剩余|参考文献|PRIMARY,fk_替换_模型_编号_依据,fk_替换_物理_物料_类型|fk替换物理物料类型|八个|常数,常数|三个|使用索引|
| 一个|简单型|锰|eq_参考|PRIMARY,型号编号unq_idx2,fk型号编号用户c,fk型号编号用户u,fk型号编号产品类型|主要|四个|vat_warehouse.r.按标识列出的模型编号|一个|使用where|
| 一个|简单型|乌|eq_参考|主要|主要|一个|增值税_仓库.mn.更新人|一个||
| 一个|简单型|点|eq_参考|主要|主要|四个|vat_仓库.mn.产品类型标识|一个||
| 一个|简单型|米|eq_参考|主要|主要|四个|vat_仓库.mn.制造商标识|一个||
| 一个|简单型|铜|eq_参考|主要|主要|一个|增值税仓库制造商创建人|一个||
| 一个|简单型|马|参考文献|旧Map唯一索引,fk旧Map物理物料类型|旧Map唯一索引|八个|vat_warehouse.r.按标识列出的模型编号,常数|一个|使用索引|
下面是一个来自未使用索引服务器的查询计划:
| 标识符|选择类型(_T)|工作台|类型|可能的密钥|钥匙|密钥长度|参考文献|列|额外的|
| - -|- -|- -|- -|- -|- -|- -|- -|- -|- -|
| 一个|简单型|剩余|参考文献|PRIMARY,fk_替换_模型_编号_依据,fk_替换_物理_物料_类型|fk替换物理物料类型|八个|常数,常数|一个|使用索引|
| 一个|简单型|米|全部|主要|空值|空值|空值|一个|使用连接缓冲区(平面、BNL连接)|
| 一个|简单型|点|全部|主要|空值|空值|空值|一个|使用联接缓冲区(增量、BNL联接)|
| 一个|简单型|铜|全部|主要|空值|空值|空值|一个|使用联接缓冲区(增量、BNL联接)|
| 一个|简单型|乌|全部|主要|空值|空值|空值|一个|使用联接缓冲区(增量、BNL联接)|
| 一个|简单型|锰|eq_参考|PRIMARY,型号编号unq_idx2,fk型号编号用户c,fk型号编号用户u,fk型号编号产品类型|主要|四个|vat_warehouse.r.按标识列出的模型编号|一个|使用where|
| 一个|简单型|马|参考文献|旧Map唯一索引,fk旧Map物理物料类型|旧Map唯一索引|八个|vat_warehouse.r.按标识列出的模型编号,常数|一个|使用索引|

相关问题