【问题标题】:Mysql join or php in_array() which is better to optimize Mysql query?Mysql join 或 php in_array() 哪个更好优化 Mysql 查询?
【发布时间】:2013-08-19 10:23:24
【问题描述】:

我正在尝试为我当前的项目实现监视列表功能,用户可以在其中将项目添加到他们的监视列表中。

因此,直到将项目添加到监视列表工作正常,但是当显示特定类别中的所有项目(在监视列表中而不是集中在监视列表中)时,我需要检查用户监视列表中的项目是否以及它是否不在监视列表我必须显示一个添加到监视列表的按钮.....如果它已经在监视列表中,请使用一个按钮将其删除。

所以在这里我有以下表格

观察名单

item-id(int)
用户名
添加日期(到观察列表)

项目
项目 ID(int)
物品名称
项目描述
添加日期
用户
用户名
fname
lname
加入日期

目前用户访问商品页面时,mysql查询次数
1 查询用户检查(如果登录在页面顶部获取用户名)
1 个用于显示文章的查询(使用类别过滤器)
许多查询以显示某个项目是否在监视列表中。
我在一个循环中使用一个查询,它检查 watchlist 表中的 usernameitem-id 对,并获取 item-id 并将其与目前的文章并决定它是否在观察列表中(我知道这是一个不好的方法......但我用它作为开始,因为我是一个初学者)
如果每页显示 20 个项目,则将有 20 个查询,如果 30 个项目 30 个查询等等....所以我才开始想办法优化它。

一个 我正在考虑实现的方法是通过一个查询到一个数组来获取 watch-list 表中的所有 item-id 并使用 php 检查in_array() 在将项目打印到页面并正确打印之前

我认为这目前很好。但由于我是初学者,我想学习优化查询的最佳实践
这样做好不好,或者你们中的一些人可以建议其他技术。

你们中的一些人可能会建议使用连接.......但我不知道如何在这种情况下使用它们。如果这是一种更好的方法......有人可以解释我如何在此使用连接场景

提前致谢
什里坎特

【问题讨论】:

  • 根据经验,查询是昂贵的:它们意味着返回数据库服务器,可能需要打开/关闭连接,并且在许多情况下还将查询写入日志文件,它增加了更多的 I/O。 less 您可以使用的查询越好。如果您可以将 n 个查询替换为单个查询,请执行此操作。 O(1) 比 O(n) 要好。
  • 在一个查询中而不是循环中为用户获取已观看项目的列表是一种显而易见的优化,可以轻松完成,一个简单的内部连接与项目过滤类别就足够了。您甚至可以将联接监视列表表留给您的行集以用于显示文章的查询,但是您必须对其进行测试,因为对每个用户使用不同的查询可能会对查询缓存产生不良影响,而且我们看不到您实际上是如何处理该类别的过滤。
  • @Piotrm 感谢您的建议。为了进行类别过滤,项目表中有 (3) 更多列用于对项目进行分类。但我没有在问题中显示它们。是的,每个用户的查询都会有所不同....如果是这样你能建议任何其他可能的替代方案

标签: php mysql


【解决方案1】:

您的想法是正确的,最好使用连接,因为这可能会为您节省每个项目的额外查询。

您现在必须做的:使用left join 来确定该条目是否被列入观察名单。 (如果不是,则连接的右手结果将为空。

看起来像这样(未经测试):

选择当前用户的所有关注列表项。

SELECT 
 i.* 
FROM
 items i
LEFT JOIN
 watch-list wl
ON
  i.item-id = wl.item-id AND
  wl.user-id = {$currentUserId}
WHERE
  NOT isnull(wl.item-id) --if theres a right side, its watchlisted

Vice Versa,选择所有未关注列表

SELECT 
 i.* 
FROM
 items i
LEFT JOIN
 watch-list wl
ON
  i.item-id = wl.item-id AND
  wl.user-id = {$currentUserId}
WHERE
  isnull(wl.item-id) 

选择所有项目并插入一个标志以确定该项目是否被列入观察名单。

SELECT 
 i.*,
 IFNULL(wl.item-id, "0") as watchlisted -- will be > 0 if watchlisted.  
FROM
 items i
LEFT JOIN
 watch-list wl
ON
  i.item-id = wl.item-id AND
  wl.user-id = {$currentUserId}

【讨论】:

  • 感谢您的宝贵建议。你帮我弄清楚该怎么做。我会努力实现这个
  • 但是我还必须计算监视列表中的项目总数。所以早些时候,通过一个查询,我只是将监视列表中的所有项目添加到一个数组中,计算该数组中的条目数显示监视列表中的项目总数(用于导航,例如:**Watchlist(3)**),然后再进行一次查询以根据过滤器检索所有项目并使用 php in_array() 函数检查以显示它是否在监视列表中与否。使用 Left Join 我想我还需要一个查询来计算监视列表中的项目总数。这两种方法都会导致我 2 个查询。有没有其他建议来获得项目总数?
  • @Shrikanth:获取所有关注列表项后,只需使用mysql_num_rows()
  • 我认为你没有得到我的问题。我需要做 2 件事。一个显示监视列表中的项目总数(通过网站)用于导航目的。第二个显示项目令人满意到类别过滤器。在显示属于某个类别的文章时,我需要检查每个项目是否在关注列表中并相应显示(添加到关注列表/InWatchlist-Remove)。并且是的,使用 Left Join 我可以完美地完成第二部分。但是计算关注列表中的所有项目我还需要一个查询 SELECT COUNT('item-id') FROM watchlist WHERE user='$current_user ' .2 再次查询。
猜你喜欢
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
相关资源
最近更新 更多