【问题标题】:Does this query fetch unnecessary information? Should I change the query?此查询是否获取不必要的信息?我应该更改查询吗?
【发布时间】:2011-02-16 20:33:35
【问题描述】:

我有这个分类网站,我在 MySql 中有大约 7 个表,所有数据都存储在其中。 我有一个主表,称为“分类广告”。

在分类表中,有一个名为分类_id 的列。这不是PK,也不是钥匙。它只是一个数字,用于我将表记录连接在一起。

例如:

 classifieds table:           fordon table:
       id => 33                   id => 12
classified_id => 10             classified_id => 10
  ad_id => 'bmw_m3_92923'           

以上内容通过分类id列链接在一​​起。

现在到 Q,我使用此方法获取列 ad_id 与数组中的任何值匹配的所有记录,在本例中称为 $ad_arr:

SELECT mt.*, fordon.*, boende.*, elektronik.*, business.*, hem_inredning.*, hobby.*
    FROM classified mt
    LEFT JOIN fordon ON fordon.classified_id = mt.classified_id
    LEFT JOIN boende ON boende.classified_id = mt.classified_id
    LEFT JOIN elektronik ON elektronik.classified_id = mt.classified_id
    LEFT JOIN business ON business.classified_id = mt.classified_id
    LEFT JOIN hem_inredning ON hem_inredning.classified_id = mt.classified_id
    LEFT JOIN hobby ON hobby.classified_id = mt.classified_id 
    WHERE mt.ad_id IN ('$ad_arr')";

这样好还是真的会获取不必要的信息?

查看我几天前发布的这个问题。在 cmets HLGEM 评论说它是错误的等等等等。你怎么看?

Another rookie question; How to implement Count() here?

谢谢

【问题讨论】:

  • 你应该接受 HLGEM 的回答,他昨天和今天都是对的。

标签: php sql mysql html database


【解决方案1】:

这是一个见仁见智的问题。您是否遇到性能或扩展问题?如果不是,那么具体返回哪些列可能是过早优化的问题。整数连接列的重复不会很快破坏带宽库。

【讨论】:

  • -1 不是意见或品味的问题。通过仅选择您需要的列,您可以最大限度地提高仅通过索引即可满足查询的机会,并减少整体查询处理工作量。
  • 我希望网站成功,Camran。一旦您开始在处理请求时遇到问题,那么您应该考虑输入每个列名。 Web 框架(Cake、Django、Rails 等)也可以使这更容易。例如,Django 让您使用“defer”和“only”方法选择您需要的列,然后为您生成 sql。
  • 因此,当性能突然成为问题时,灭火比一开始就采取相当简单的方法要好?
  • 当您擅长开发并使用 SQL 更上一层楼时,您会发现覆盖索引,其中您在索引中包含不属于索引的数据(附加列)。然后数据库可以使用这些列并返回结果,而无需从索引查找返回到表。如果你总是选择 * 你不能使用覆盖索引,因为你要求所有的列。当您调整慢速查询时(现在速度很快,因为应用程序未运行且没有数据),您将无法使用此技术。
  • @marr75 - 我理解你的意思,但这通常被认为是 SQL 101,而不是高级优化。
【解决方案2】:

您肯定会返回不必要的结果来回答您的问题。

这是一个坏习惯。

【讨论】:

  • 那应该怎么写呢?选择表名。列名?如果有很多列怎么办,那将是一个很长的查询,对吧?
  • @Camran,你选择:一个长的 SELECT 语句,或者一个更长的结果集乘以行数。
  • 您可以使用缩写表名作为别名,这会缩短查询时间。当然,通过命名列查询会更长,但作为程序员,我们不能偷懒。
  • 我不知道 mySQl 但在 SQL Server 中我可以将列拖放到我的查询中,因此列出它们根本不需要太多时间。
【解决方案3】:

强烈反对marr75。首先,如果您在大多数查询中都使用这种糟糕的技术,那么您实际上会为每个查询添加不必要的负载。数据库查询需要尽可能优化地编写,因为以后去 bnack 并重写数据库中的每个查询是非常痛苦的,因为您使用了一种已知的糟糕技术。数据库中的重构是困难的,在设计中必须考虑性能,使用已知的从一开始就可以提高性能的技术并不是过早的优化,这是好的设计。

接下来,您遇到了维护问题。如果您依赖这些列按特定顺序排列并且有人更改了数据的结构,那么您就大错特错了。另外,如果有人添加了您不想向用户显示的列(这很常见),那么您就不走运了。这是一个非常糟糕的技术,并且 select * 几乎不应该在生产系统中使用。如果有人添加了一列,它将在查询中返回,但您需要知道添加了什么以及添加的原因,以便让界面做它需要做的事情,因此使用这种糟糕的技术不会节省维护费用。

【讨论】:

  • +1,浪费一秒钟,哦,好吧。每天浪费一百万次,哦*%$@!不要偷懒,只返回你需要的列!
【解决方案4】:

即席查询

这些是您编写运行一次或在极少数情况下运行的查询。

您必须返回多大的结果数据集才能使SELECT * 比输入列名花费更长的时间?

您忘记列、添加它并不得不再次运行它的可能性有多大?

您的时间比 CPU 时间更昂贵。如果你只运行一次,就让数据库来完成这项工作。 SELECT * 适用于即席查询,如果它可以节省您的时间。

也有例外,例如大型数据集上的 Blob 字段,但您明白这一点。

生产查询

这些是存储在您的应用程序或数据库中的查询。这些查询经常运行。

您需要运行多少次查询才能弥补为列命名所花费的时间?它加起来很快。

为生产查询中的列命名,以使您的应用程序能够更好地扩展并以最高效率运行。还有其他一些小优势,但没有那么令人兴奋。

总结

  • 添加临时查询:SELECT * 通常没问题。
  • 生产查询:SELECT * 总是不好。
  • 懒一点没关系,但要聪明一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-07
    • 2014-05-08
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    相关资源
    最近更新 更多