繁体   English   中英

如何减少规范化数据库中的查询数量?

[英]How to reduce the number of queries in a normalized database?

想象一下一张摆有物品的桌子。 除了主要查询:

SELECT * From articles WHERE article_id='$id'

我们还需要其他几个查询来获取

SELECT * FROM users WHERE user_id='$author_id' // Taken from main query

SELECT tags.tag 
FROM tags 
  INNER JOIN tag_map 
    ON tags.tag_id=tag_map.tag_id 
WHERE article_id='$id'

以及更多关于类别,类似文章等的查询

问题1:是用PHP单独执行这些查询并处理给定结果的最佳方法,还是有将它们组合的最佳方法?

问题2:在没有many-to-many关系的情况下(例如,每个标签,类别,作者由tag_id,category_id,author_id标识的每篇文章); 最好(最快)的是从表中检索数据。

如果所有关系都是一对多的,那么您可以很容易地在一个查询中检索所有这些数据,例如

SELECT
    [fields required]
FROM
    articles a
    INNER JOIN
        users u ON a.author_id=u.user_id
    INNER JOIN 
        tag_map tm ON tm.article_id=a.article_id
    INNER JOIN
        tags t t.tag_id=tm.tag_id
WHERE
    a.article_id='$id'

通常,这比单独的三个查询要快,因为您的表已正确建立索引,因为MySQL是为此而建立的! 这样可以节省两次往返数据库的时间以及相关的开销。

您可以在第一个查询中合并用户:

SELECT a.*, u.*
FROM   articles a
JOIN   users u ON u.user_id = a.author_id
WHERE  a.article_id='$id';

可以对标签进行相同的操作,但这会在答案中引入一些冗余,因为每篇文章显然有多个标签。 可能会或可能不会有好处。

在没有many-to-many关系的情况下,这将一举完成这项工作,并且在任何情况下都将是优越的:

SELECT *
FROM   users u
JOIN   articles a ON a.author_id = u.user_id
JOIN   tag t      USING (tag_id)  -- I assume a column articles.tag_id in this case
WHERE  a.article_id = '$id';

您可能希望对要返回的列更具选择性 如果不能保证存在标签,则使第二个JOIN成为LEFT JOIN

您可以在规范化表上添加适当的非规范化视图,其中每个记录都包含所需的所有数据。 或者,您可以将SQL调用封装在存储过程中,然后从代码中调用这些proc,这应有助于提高性能。 证明并得到困难的数字; 总是最好根据证据而不是想法来做出决定。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM