从PHP优化数据库查询

时间:2013-03-11 20:33:27

标签: php mysql sql pdo

我正在构建一个类似Pinterest的网站,处于发展的早期阶段。

我可以毫无问题地做到这一点,但我很想知道这是否是最佳方式。

目的:

从数据库中提取所有图像数据,然后为每个图像数据从“收藏夹”表中提取数据,计算照片的收藏夹,然后,如果存在活动用户会话,则将用户标记为收藏夹。

问题

该网站默认显示54张照片,然后,对于这54张照片,该程序必须查看每个照片的收藏夹。 这代表了对服务器和数据库的许多请求,我认为它的形式如下:

$images = 'SELECT * FROM IMAGES photo_id ORDER BY LIMIT 54';

foreach ( $images as $image ) {
   $lookFavorite = 'SELECT * FROM favorites WHERE photo_id ='. $ image ['photo_id'] ';
}

数据库表结构

照片

photo_id    INT (auto increment)
user_nick   VARCHAR (25)
photo_path  VARCHAR (255)
photo_title VARCHAR (150)
photo_theme VARCHAR (60)
date        TIMESTAMP

收藏夹

photo_id  INT
user_nick VARCHAR (25)
date      TIMESTAMP

重要

PHP version 5.3, using MySQL.
The program I'm building is object oriented [I'm using PDO'].

4 个答案:

答案 0 :(得分:2)

您应该使用从图像到收藏夹的左连接,然后根据需要使用GROUP BY来获取您的计数,以防有图像有0个收藏夹。

SELECT * 
FROM `images` 
LEFT JOIN `favorites` ON `images`.`photo_id`=`favotites`.`photo_id`

答案 1 :(得分:0)

放弃循环并执行

$lookFavorite = 'SELECT * FROM favorites';

创建一个包含所有内容的数组,然后根据您从

获取的内容循环显示您需要的内容
$images = 'SELECT * FROM IMAGES photo_id ORDER BY LIMIT 54';

这样,只有两个查询而不是55

$images = 'SELECT * FROM photos INNER JOIN favorites ON (favorites.photo_id = photos.photo_id) ORDER BY favorites.photo_id LIMIT 54';

在单个查询中执行

答案 2 :(得分:0)

我认为你在这里寻找的是LEFT JOIN。

SELECT * FROM images
LEFT JOIN favorites
ON images.photo_id = favorites.photo_id
WHERE images.photo_id IN (..array populated from first query..)

如果您需要将结果限制为前54个图像,那么您可以使用适当的谓词填充JOIN的WHERE子句。

作为旁注,我选择LEFT JOIN是因为我想在列表中包含所有图像,即使它们没有收藏夹,但我想包含与图像无关的收藏夹我想要。

答案 3 :(得分:0)

1如果您不需要所有字段,请不要使用*。

在您的服务器上进行测试,但我认为此解决方案可以更快地运行

$images = 'SELECT photo_id, photo_path FROM photos LIMIT 54';
$ids = array();
foreach ( $images as $image ) {
  $ids[]= $image ['photo_id'];
}

$lookFavorite = 'SELECT * FROM favorites WHERE photo_id in ('. implode(',',$ids). ')';