There are 3 tables: posts (post) tags (tag) link tags and posts (post_tag)
Standard link table
post_id | tag_id 1 | 4 1 | 6 2 | 5 3 | 6 4 | 5 4 | 7 6 | 8 7 | 8 It is necessary to get all posts that do not have tags 4 and 5 (and an additional condition is the exclusion of already viewed posts, let's say looked posts with id 6 and 7)
I make a request:
SELECT post_id FROM post_tag WHERE post_id NOT IN ( SELECT DISTINCT post_id FROM post_tag WHERE tag_id IN (4,5) ) AND post_id NOT IN (6,7)
mysql> explain SELECT DISTINCT `idVideo` FROM `video_tag` WHERE `idVideo` NOT IN (SELECT DISTINCT idVideo FROM video_tag WHERE idTag IN (263,469,478,482,537,904,967)) AND (`idVideo`<>239529) AND (`quality`=100); +----+-------------+-----------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+---------+------+---------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+---------+------+---------+--------------------------+ | 1 | PRIMARY | video_tag | index | PRIMARY,video_tag-idVideo-video-id,video_tag-idVideo-idTag,video_tag-idVideo-idTag-quality,video_tag-idTag-idVideo-quality,video_tag-idTag-idVideo,video_tag-idTag,video_tag-idVideo | video_tag-idVideo-video-id | 4 | NULL | 4629680 | Using where | | 2 | SUBQUERY | video_tag | range | PRIMARY,video_tag-idVideo-video-id,video_tag-idVideo-idTag,video_tag-idVideo-idTag-quality,video_tag-idTag-idVideo-quality,video_tag-idTag-idVideo,video_tag-idTag,video_tag-idVideo | PRIMARY | 4 | NULL | 372807 | Using where; Using index | +----+-------------+-----------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+---------+------+---------+--------------------------+ 2 rows in set (0.01 sec) The number of indices for the test.
The request works terribly slowly. How to speed up this thing?
explain ваш-запросwithexplain ваш-запрос, for postgress it is the same) - MikeNOT IN (SELECT ...)withNOT EXISTS (SELECT ...), - Yaant