优化MySQL中的三个表连接

时间:2010-11-10 17:16:38

标签: sql mysql

我正在构建一个电子库,我编写了一个查询,可能会因为索引不佳而扫描更多行。这是我的表结构。

  1. book_categories(cat_id,parent_id DEFAULT NULL,cat_name,parent_cat_name DEFAULT NULL)
  2. authors(author_id,author_name,active)
  3. books(book_id,cat_id,author_id,book_title,book_contents,book_status ENUM(已发布,待定,已删除)publish_date)
  4. 这是SQL代码

      SELECT T.author_id, 
             T.author_name, 
             C.parent_id, 
             C.cat_id, 
             C.cat_name, 
             B.book_id, 
             B.book_title, 
             B.book_contents, 
             B.publish_date 
        FROM books B, 
             authors T, 
             book_categories C 
       WHERE B.author_id = T.author_id 
         AND C.cat_id = B.cat_id 
         AND book_status = 'published' 
    ORDER BY published_date DESC
    

    解析上述查询

    id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
    -----------------------------------------------------------------------------------------------------
    1   SIMPLE  C   ALL     PRIMARY     NULL    NULL    NULL    449     Using where; Using temporary; Using filesort
    1   SIMPLE  B   ref     author_id,cat_id    cat_id  4   bookdb.C.cat_id     214     Using where
    1   SIMPLE  T   eq_ref  PRIMARY     PRIMARY     4   bookdb.B.author_id  1    
    

    索引&键

    Alter table books 
    add Foreign Key (author_id) references authors (author_id) on delete  restrict on update  restrict;
    
    Alter table books 
    add Foreign Key (cat_id) references book_categories (cat_id) on delete  restrict on update  restrict;
    
    Create Index books_INX ON books(cat_id,book_status,published_date);
    

3 个答案:

答案 0 :(得分:1)

你的索引很好。只要它快速完成,不要担心它扫描几百行(约占表的0.5%)。它够快吗?

答案 1 :(得分:0)

我没有看到在这些表上创建任何索引...如果没有索引,不要指望MySQL在“即时”创建它们并使用它们。如何定义一些?

http://dev.mysql.com/doc/refman/5.0/en/create-index.html

答案 2 :(得分:0)

尝试将author_id添加到索引books_INX。尝试将published_date移至books_INX中的其他位置(第一个,最后一个......)。例如:

Create Index books_INX ON books(cat_id,author_id,book_status,published_date);

确保author_idcat_id分别是authorbook_category表的主键。同样book_id应该是books表的主键,即使它不应该影响这个特定的查询。