我将MySQL
与InnoDB
引擎一起使用。
我有两张桌子:
CREATE TABLE `video` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB;
CREATE TABLE `tags` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`videoId` INT(11) NOT NULL,
`title` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`),
INDEX `fk_video_tags_idx` (`videoId` ASC),
CONSTRAINT `fk_video_tags`
FOREIGN KEY (`videoId`)
REFERENCES `video` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
) ENGINE = InnoDB;
video
表有~500,000和tags
~400,000条记录。
我写一个简单的查询是这样的:
SELECT *
FROM `video`
LEFT JOIN `tags` ON (video.id = tags.videoId)
WHERE video.id='1' OR tags.id='1'
对我来说,使用OR
操作时使用两个条件非常重要。
id
中的WHERE
字段仅用于示例查询,我不确定结果记录的数量,因此我不能也不想使用LIMIT
。< / p>
此查询执行时间约为3秒。这很糟糕,但是当情况更糟时,tags
表有大约5,000,000条记录!在这种情况下,执行时间约为160秒!那太糟糕了。
那么,什么是改善执行时间和提高性能的解决方案?
答案 0 :(得分:2)
我有时想将OR
分成不同的SELECT
和UNION
结果。
默认情况下,UNION
在结合结果集时具有隐式DISTINCT
。
如果这不足以让你的速度降低,那么你可以单独运行每一半,看看绝对最短时间是多少。 (对于每一半数据)
SELECT *
FROM `video`
LEFT JOIN `tags` ON (video.id = tags.videoId)
WHERE video.id='1'
UNION
SELECT *
FROM `video`
LEFT JOIN `tags` ON (video.id = tags.videoId)
WHERE tags.id='1'
答案 1 :(得分:1)
尝试选择可能有用的标签并将它们存储在mytags临时表中并加入此标签而不是巨大的标签表:
SELECT *
FROM `video`
JOIN
( SELECT * FROM tags WHERE id=1 or videoid=1) as mytags -- (*)
ON (video.id = mytags.videoId)
(*)注意:
如果在video.id = tags.videoId
条件上加入表格并设置WHERE
条件video.id='1' OR tags.id='1'
,则表示选择符合(video.id = 1 = tags.videoId
)OR
tags.id=1
条件的标记。所以我先建议SELECT
,然后加入新的缩小标签表。