Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MySQL高效选择查询_Php_Mysql - Fatal编程技术网

Php MySQL高效选择查询

Php MySQL高效选择查询,php,mysql,Php,Mysql,我不是数据库专业人士,但目前正在处理一个查询(PHP->MySQL): 我有三张桌子: “项目”:id、名称、链接 “ItemsToUsers”:id、item\u id、用户\u id “用户”:id,电子邮件 每个“项目”的可用性都会定期进行更改,我会通过某种算法进行动态检查 我的目标是 1) 选择所有项目并动态检查是否可用 2) 如果项目可用,请通过电子邮件通知正在监视该项目的用户。为此,我需要从“ItemsToUsers”中选择用户,然后从users表中获取他们的电子邮件 我知道如何以一

我不是数据库专业人士,但目前正在处理一个查询(PHP->MySQL):

我有三张桌子:

“项目”:id、名称、链接

“ItemsToUsers”:id、item\u id、用户\u id

“用户”:id,电子邮件

每个“项目”的可用性都会定期进行更改,我会通过某种算法进行动态检查

我的目标是

1) 选择所有项目并动态检查是否可用

2) 如果项目可用,请通过电子邮件通知正在监视该项目的用户。为此,我需要从“ItemsToUsers”中选择用户,然后从users表中获取他们的电子邮件

我知道如何以一种简单的方式进行,但我觉得我会陷入许多查询中。(为每个用户单独选择…)

有没有更有效的方法:在一个查询中,还是通过更改算法?
谢谢你抽出时间

没有足够的信息来确定项目的可用性。这严重妨碍了查询第2项的能力

也就是说,假设我们在Items表中添加了一个“available”列,其中0表示不可用,1表示可用

SELECT u.email FROM Users AS u JOIN ItemsToUsers AS k ON k.user_id = u.id WHERE k.item_id IN (SELECT a.item_id FROM Availability AS a WHERE a.available = 1);
然后,一个查询将获取观看可用项目的人员的所有电子邮件地址,该查询是:

 SELECT u.email FROM Users AS u JOIN ItemsToUsers AS k ON k.user_id = u.id JOIN Items AS i on i.id = k.item_id WHERE i.available = 1;
或者,您可以使用子查询并在中使用

假设您有一个名为Availability的不同表,其列id、item_id和available,这也是一个tinyint,其中1表示available,0表示NotAvailable

SELECT u.email FROM Users AS u JOIN ItemsToUsers AS k ON k.user_id = u.id WHERE k.item_id IN (SELECT a.item_id FROM Availability AS a WHERE a.available = 1);

同样,如果不知道如何获取可用产品列表,就不可能优化查询以检索电子邮件地址列表。

您的步骤暗示了在中执行此操作(其中n=Items表中的条目数):

在迭代该结果集时,您需要确定该结果集是否可用,如果可用,则通知正在观看该结果集的用户。假设您有一个给定的项目id,并且如果该产品id处于活动状态,您希望选择所有用户的电子邮件,那么您可以执行以下操作:

SELECT email FROM Users u 
    INNER JOIN ItemsToUsers iu ON iu.user_id = u.id
    INNER JOIN Items i ON iu.item_id = i.id
WHERE i.id = {your item id}
您将对表中的每个项运行此查询。这是第n部分

通常,您可以在确定哪些产品应处于活动状态后,为正在观看所有活动产品的所有用户生成电子邮件列表:

SELECT DISTINCT email FROM Users u 
    INNER JOIN ItemsToUsers iu ON iu.user_id = u.id
    INNER JOIN Items i ON iu.item_id = i.id
WHERE i.is_active = 1

这将在总共2个查询中完成工作,而不管您有多少用户或项目。作为奖励,此解决方案可以为您提供不同的电子邮件,而第一个解决方案仍然需要应用程序级代码来删除多个查询返回的重复项。

让我们来看看您需要的选择的模型。可能您只需要一个SELECT with JOIN就可以连接三个表。请使用,不要忘记连接列上的索引。您的“可用性”列在哪里?我只能看到项目的id、名称和链接。我没有将可用性状态存储在任何地方-我只是在foreach($result as$row){}期间动态检查它。但是我可能首先考虑检查它们,然后存储那些可用的,然后获得电子邮件。感谢您提供的查询示例。这是您的瓶颈。我建议更改您的算法,直接查询可用产品。但是,如果不容易做到这一点,可以创建一个存储过程,该过程接受一个ID数组并返回带有这些ID的所有记录。请参见devart在(选择…)
中的回答,不要养成
的习惯——性能非常差。正确;子查询通常是个坏主意。但是与运行数百个查询相比,它们可能是更好的选择。是的,你理解我对运行太多查询的担忧-我真的很喜欢你的解决方案。我只是阅读了你的评论,你没有为项目实际存储可用性标志,因此如果你想使用此解决方案,你需要它才能查询。希望这有帮助!听起来很像我的答案。
SELECT  Items.id, Items.name, Items.link FROM Items
INNER JOIN ItemsToUsers ON ItemsToUsers.item_id = Items.items.id
INNER JOIN Users  ON ItemsToUsers.user_id = Users.id ;