使用多个左连接优化MySQL查询

Vij*_*ati 10 mysql sql optimization

我有一个NewsStories表,我还要加入一些相关的表.每个新闻故事可以有多个图像,类别和地址.所以查询本质上是:

SELECT * FROM NewStories 

LEFT JOIN Images ON Newstories.id=Images.story_id

LEFT JOIN Categories ON NewsStories.id=Categories.story_id

LEFT JOIN Addresses ON NewsStories.id=Addresses.story_id

WHERE ...
Run Code Online (Sandbox Code Playgroud)

每个故事通常有一些图像和地址,以及1或2个类别.NewsStories表有大约10,000篇文章.

麻烦的是性能相当慢(大约15-20秒,虽然它确实变化很大,有时下降到5秒).

我想知道是否有更好的方法来组织查询以加快速度(我对SQL很新).

特别是,给定故事的行数乘以图像数乘以地址数乘以类别数量似乎相当浪费.

我基本上试图将新闻故事的属性重建为一个我可以在前端操作的对象.

这是解释(如果格式化不正确,请道歉).我猜我没有正确索引地址,如果它是"使用在哪里".那是对的吗?

id  select_type table   type    possible_keys   key key_len ref rows    Extra

1   SIMPLE  Addresses   ALL NULL    NULL    NULL    NULL    6640    Using where

1   SIMPLE  NewsStories eq_ref  PRIMARY PRIMARY 767 NewsStories.Addresses.story_id 1    Using where

1   SIMPLE  Images  ref PRIMARY PRIMARY 767 NewsStories.NewsStories.id  1   Using index

1   SIMPLE  Categories  ref PRIMARY PRIMARY 767 NewsStories.NewStories.id   1
Run Code Online (Sandbox Code Playgroud)

Mar*_*yor 8

  • 确保在WHERE语句和ON条件中的字段上有索引,默认情况下会对主键建立索引,但如果必须,还可以手动创建索引.

CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name [index_type] ON tbl_name(index_col_name,...)[index_type]

index_col_name:col_name [(length)] [ASC | DESC]

index_type:USING {BTREE | HASH}

  • 检查是否真的必须选择所有表中的每一列?如果没有,请确保您只选择所需的列,避免使用select*

  • 仔细检查你是否真的需要LEFT JOINS,如果没有,请使用INNER JOIN.

  • 如果在完成调整查询后仍然存在性能问题,请考虑对模式进行非规范化以消除连接

  • 您可能还想考虑使用sphinxsearch和memcached等缓存应用程序来减少数据库的负载

  • 检查您的联接都不是视图而不是实际表

引用:

http://www.sphinxsearch.com

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