【问题标题】:What is wrong with my index on this MySQL query?我在这个 MySQL 查询上的索引有什么问题?
【发布时间】:2010-07-27 22:31:28
【问题描述】:
select
                xml_record_product.product_id, 
                IfNull(xml_record_product.product_short_description,xml_record_product.product_description) AS BookDescription, 
                xml_record_product.product_image, 
                xml_record_product.product_publisher_name AS Publisher, 
                xml_record_product.product_title AS BookTitle, 
                xml_record_product.product_form, 
                xml_record_product.product_num_pages, 
                xml_record_product.product_BASICMainSubject, 
                xml_record_product.product_BICMainSubject, 
                xml_record_product.product_audience_code, 
                xml_record_product.product_country_of_publication, 
                xml_record_product.product_publishing_status, 
                xml_record_product.product_publication_date AS BookDate, 
                xml_record_product.product_imprint, 
                xml_record_product.product_active, 
                xml_record_product.product_isFeatured, 
                xml_record_product.product_isNewArival, 
                xml_record_product.product_short_description, 
                xml_record_product.product_description, 
                xml_record_product.product_isbn13 AS ISBN,
                xml_record_subject.subject_heading_text
                FROM xml_record_product 
                inner join xml_record_contributor ON xml_record_product.product_id = xml_record_contributor.product_id
                inner join xml_record_subject on xml_record_contributor.product_id = xml_record_subject.product_id
                inner join xml_record_supplier on xml_record_product.product_id = xml_record_supplier.product_id AND supplier_price > 0
                where contributor_title like '%josh%'
                order by xml_record_product.product_publication_date DESC limit 20;

给予:

SIMPLE xml_record_supplier index sup_product_id sup_product_id 265  895424 Using where; Using index; Using temporary; Using filesort

SIMPLE xml_record_subject ref product_id_sub product_id_sub 8 mysupplier1.xml_record_supplier.product_id 1 

SIMPLE xml_record_product eq_ref PRIMARY PRIMARY 8 mysupplier1.xml_record_supplier.product_id 

SIMPLE xml_record_contributor ref cont_product_id cont_product_id 8 mysupplier1.xml_record_subject.product_id 1 Using where

但如果我取出 xml_record_supplier 上的内部连接,我会得到:

SIMPLE xml_record_product index PRIMARY pub_date 265  20 

SIMPLE xml_record_subject ref product_id_sub product_id_sub 8 mysupplier1.xml_record_product.product_id 1 

SIMPLE xml_record_contributor ref cont_product_id cont_product_id 8 mysupplier1.xml_record_subject.product_id 1 Using where

我需要知道为什么会发生这种情况,以及如何预防?据我了解, EXPLAIN 将显示从内部连接顺序读取的表。这没有发生,并且我确保我在这些查询中的 product_id 上设置了索引(对于 xml_record_contributor,它是 product_id 和 contributor_id 的混合)

在 xml_record_supplier 上,我在索引中有 product_id 和 supplier_price(但是,我也尝试了很多组合,想一想)

有什么我可以尝试的想法吗?我需要将选择限制为价格高于 0 的供应商,并且添加该内部连接后,它很快就会失控。

感谢您的任何意见!

/edit- 这是所有表格的描述

xml_record_product (index is product_id,product_publication_date desc)

product_id  bigint(20)  NO  PRI     auto_increment
    product_isbn13  bigint(13)  NO          
    product_form    varchar(255)    NO          
    product_num_pages   int(11) NO          
    product_BASICMainSubject    varchar(255)    NO          
    product_BICMainSubject  varchar(255)    NO          
    product_audience_code   int(11) NO          
    product_country_of_publication  varchar(255)    NO          
    product_publishing_status   int(11) NO          
    product_publication_date    varchar(255)    NO  MUL     
    product_short_description   varchar(350)    NO          
    product_description text    NO          
    product_imprint varchar(255)    NO          
    product_image   varchar(255)    NO          
    product_publisher_name  varchar(255)    NO          
    product_title   varchar(255)    NO          
    product_active  int(11) NO      1   
    cat_id  int(11) NO          
    product_isFeatured  int(11) NO          
    product_isNewArival int(11) NO  

xml_record_contributor(索引为product_id,contributor_id)

contributor_id  int(11) NO  PRI     auto_increment
product_id  bigint(20)  NO  MUL     
contributor_title   varchar(255)    NO          

xml_record_supplier(索引为 product_id,supplier_id,supplier_price)

supplier_id int(11) NO  PRI     auto_increment
product_id  bigint(20)  NO  MUL     
supplier_name   varchar(255)    NO          
supplier_product_availability   int(11) NO          
supplier_price  varchar(255)    NO          
supplier_currency_code  varchar(255)    NO          
supplier_supply_to  varchar(255)    NO          
supplier_price_status   varchar(255)    NO          
Description text    NO          
URL varchar(255)    NO          
Image1  varchar(255)    NO          
Image1_sml  varchar(255)    NO          
Image1Alt   varchar(255)    NO          

xml_record_subject(索引为subject_id,product_id)

subject_id  int(11) NO  PRI     auto_increment
product_id  bigint(20)  NO  MUL     
subject_heading_text    varchar(255)    YES MUL     
ParentID    varchar(20) NO  

编辑

这是 xml_record_supplier 的 SHOW INDEX FROM

xml_record_supplier 1   sup_product_id  1   product_id  A   447712              BTREE
xml_record_supplier 1   sup_product_id  2   supplier_id A   895424              BTREE
xml_record_supplier 1   sup_product_id  3   supplier_price  A   895424              BTREE

【问题讨论】:

  • 那些索引是复合索引吗? SHOW INDEXES FROM table 将为您提供表中的所有索引。
  • 我在出现问题的表上为您添加了显示索引(内部连接时)。我不完全确定它是否是一个复合索引,但我确定它一定是。

标签: mysql database


【解决方案1】:

您能否发布一个 DESCRIBE 表,以便我们查看您的索引和表结构?

我总是让我的连接尽可能简单。将supplier_price > 0 移至WHERE 条件。我猜是因为 MySQL 试图在 xml_record_supplier 中使用索引。结果,它不能在 product_publication_date 上使用索引,这意味着它必须在没有索引的情况下进行排序。如果是这种情况,则没有简单的解决方案,因为您无法使用来自不同表的字段构建复合索引。

MySQL 的规划器更喜欢减少行数,而不是优化 ORDER BY。根据结果​​的数量、表中的行数和基数,摆脱文件排序可能会更快。尝试使用 FORCE INDEX (composite_index_on_title_and_date) 摆脱文件排序并比较结果。

【讨论】:

  • 原始代码在 WHERE 语句中的供应商价格 > 0,但将其从那里更改为内部连接和/或返回不会更改 EXPLAIN。我已按要求添加了 DESCRIBE。我确实尝试过强制索引,但它似乎根本没有帮助(删除所有索引并从头开始,MySQL 似乎选择了最佳选项)当我执行“where product_id in (select product_id from xml_record_supplier where supplier_price > 0)放弃了使用临时/使用文件排序,但由于明显的原因仍然运行缓慢。
猜你喜欢
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多