【问题标题】:Optimize three tables joins in MySQL优化 MySQL 中的三表连接
【发布时间】:2010-12-18 19:41:21
【问题描述】:

我正在建立一个电子图书馆,我编写了一个查询,它可能由于索引不佳而扫描更多行。这是我的表结构。

  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 (published,pending,deleted) publish_date)

这里是 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);

【问题讨论】:

  • @Juha Syrjälä 我添加了它们,但有些缺少它们。 author_id是authors表的主键,cat_id是book_categories的主键,book_id是books表的主键
  • 你说这个查询扫描了太多行?但是查询速度够快吗?每个表有多少行?
  • 我在这个查询中使用了 LIMIT 10,它扫描了 650 多行。超过 110K 已出版的书籍和 50K 尚未出版。如果我从此查询中删除 order by,则扫描的行数减少到 250。

标签: sql mysql


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 我在问题中添加了索引
    【解决方案3】:

    尝试将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 表的主键,即使它不应该影响这个特定的查询。

    【讨论】:

    • 我照你说的做了,但结果是一样的
    猜你喜欢
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 2019-12-30
    相关资源
    最近更新 更多