当前位置: 首页 > 面试题库 >

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

赫连秦迟
2023-03-14
问题内容

我有一个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 ...

通常每个故事有一些图像和地址,以及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

问题答案:
  • 确保在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 *

  • 仔细检查您是否确实需要左联接,如果没有,请使用INNER JOIN。

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

  • 您可能还想考虑通过使用诸如sphinxsearch和memcached之类的缓存应用程序来减少数据库的负载。

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

参考:

http://www.sphinxsearch.com

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



 类似资料:
  • 问题内容: 表架构 表名: 行:,, 我的查询模拟将一个文件夹移动到另一个文件夹,并使用IN(?)接受一个数组。 如果不存在具有相同parentId和名称的文件夹,我希望更新仅“移动”文件夹。您在任何普通文件系统下期望的行为。 因此,例如: 将会是一个查询,不检查任何有关parentId和名称的信息…但是如何使左联接起作用。 这是我尝试过的..完全不起作用。 问题答案: 所以,你要只有当目标父文件

  • 问题内容: 我有以下查询: 所以我正在使用并抓住。所以现在,我要获取该image_id并将其从图像表中转换成。 如何将其添加到查询中? 问题答案: 您可以简单地添加另一个联接,如下所示: 但是请注意,由于它是一个,如果您的消息中没有图像,则将跳过整个行。如果可能的话,您可能需要执行一次操作,该操作将仅在存在一个仪表板消息的情况下返回所有仪表板消息和一个image_filename(否则,您将获得n

  • 我有两个问题。两者都很好用: 第二个查询: 联合本: 工作正常,但我想添加左联接: DoSend工作...#1222-使用的SELECT语句具有不同的列数 你能帮我把这件事办好吗?

  • 问题内容: 我想添加代表其他表计数的列。 我有3张桌子。 留言内容 主题 星星_吉文 我要结束于: Topic_Review 因此,基本上我想在3列中附加唯一值的计数(每个主题中给定的星数,在主题中具有消息的唯一用户以及每个主题中的唯一消息数)。 我希望最终也能够过滤类别(在两列中均可见)。 此外,我最终希望按加入的人数进行排序。例如,我将要有一个按钮,该按钮按升序按“星数”排序,或按降序按“用户

  • 我想添加表示来自其他表的计数的列。 我有三张桌子。 消息 主题 STARS_GIVED 我想以: 主题回顾 所以基本上,我想附上3列唯一值的计数(每个主题中给出的星数,在主题中有消息的唯一用户,以及每个主题中唯一消息的数量)。 我希望最终能够对类别进行筛选(看看两列)。 此外,我希望最终按我加入的计数排序。例如,我将有一个按钮,按“星星的数目”按升序排序,或按“用户的数目”按降序排序,等等。 我试

  • 问题内容: 我的应用程序使用单个查询来返回用户的所有权限,并且该单个查询具有10个INNER JOIN来创建整个结果集。 这是查询的预览(由于机密信息,我不得不更改表名): 这是执行计划(创建一些索引后,成本降低了,但是返回58k行仍需要39秒): 我该怎么做才能改善此查询? 更新 这是我创建的索引: 问题答案: 感谢您添加索引的说明。要基于表8的主要条件优化查询,您希望与WHERE子句关联的列位