Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 932953
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T20:45:13+00:00 2026-05-15T20:45:13+00:00

I’m dealing with a database where items are tagged a certain number of times.

  • 0

I’m dealing with a database where items are “tagged” a certain number of times.

item (100k rows)

  • id
  • name
  • other stuff

tag (10k rows)

  • id
  • name

item2tag (1,000,000 rows)

  • item_id
  • tag_id
  • count

I’m looking for the fastest solution to:

Select items that have been tagged as X, Y, and Z (where X, Y, and Z correspond to (possibly) tag names) ?

Here’s what I have so far… I’d just like to make sure I’m doing it in the best way possible:

First get the tag_ids from the names:

SELECT tag.id WHERE name IN ("X","Y","Z");

Then I group by those tag_ids and use Having to filter the result:

SELECT item2tag.*, count(tag_id)
  FROM item2tag
  WHERE tag_id=1 or tag_id=2 or tag_id=3
GROUP BY item_id
HAVING count(tag_id)=3;

Then I can just select from item with those ids.

SELECT * FROM item WHERE id IN ([results from prior query])

I have millions of rows in item2tag, with an index on (item_id, tag_id). Is this going to be the fastest solution?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T20:45:13+00:00Added an answer on May 15, 2026 at 8:45 pm

    The method you have suggested is probably the most common way to perform the query but might not be the fastest. Using joins can be faster:

    SELECT T1.item_id
    FROM item2tag T1
    JOIN item2tag T2 ON T1.item_id = T2.item_id
    JOIN item2tag T3 ON T2.item_id = T3.item_id
    WHERE T1.tag_id = 1 AND T2.tag_id = 2 AND T3.tag_id = 3
    

    You should ensure that you have the following indexes:

    • Primary key on (item_id, tag_id)
    • Index on (tag_id).

    I performance tested this query against the original in a few different scenarios.

    • For the case where nearly every item in the table is tagged with at least one of the tags being searched for, the original query takes about 5 seconds and the JOIN version takes about 10 seconds – slightly slower.
    • For the case where two of the tags occur very frequently and one of the tags occurs only very rarely the original query takes about 0.9 seconds, whereas the JOIN query takes just 0.003 seconds – a considerable performance improvement.

    The SQL I used to make performance test is pasted below. You can run this test yourself or modify it slightly and test other queries, or different scenarios.

    Warning: Don’t run this script on your production database as it modifies the contents of the item2tag table. Running the script can take a few minutes as it creates a lot of data.

    CREATE TABLE filler (
            id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
    ) ENGINE=Memory;
    
    DELIMITER $$
    
    CREATE PROCEDURE prc_filler(cnt INT)
    BEGIN
            DECLARE _cnt INT;
            SET _cnt = 1;
            WHILE _cnt <= cnt DO
                    INSERT
                    INTO    filler
                    SELECT  _cnt;
                    SET _cnt = _cnt + 1;
            END WHILE;
    END
    $$
    CALL prc_filler(1000000);
    
    CREATE TABLE item2tag (
        item_id INT NOT NULL,
        tag_id INT NOT NULL,
        count INT NOT NULL
    );
    
    INSERT INTO item2tag (item_id, tag_id, count)
    SELECT  id % 150001, id % 10, 1
    FROM    filler;
    ALTER TABLE item2tag ADD PRIMARY KEY (item_id, tag_id);
    ALTER TABLE item2tag ADD KEY (tag_id);
    
    -- Make tag 3 occur rarely.    
    UPDATE item2tag SET tag_id = 10 WHERE tag_id = 3 AND item_id > 0;
    
    SELECT T1.item_id
    FROM item2tag T1
    JOIN item2tag T2 ON T1.item_id = T2.item_id
    JOIN item2tag T3 ON T2.item_id = T3.item_id
    WHERE T1.tag_id = 1 AND T2.tag_id = 2 AND T3.tag_id = 3;
    
    SELECT item_id
    FROM item2tag
    WHERE tag_id=1 or tag_id=2 or tag_id=3
    GROUP BY item_id
    HAVING count(tag_id)=3;
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Let's say I'm outputting a post title and in our database, it's Hello Y&#8217;all
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I want to count how many characters a certain string has in PHP, but
I want use html5's new tag to play a wav file (currently only supported
In my XML file chapters tag has more chapter tag.i need to display chapters
I would like to run a str_replace or preg_replace which looks for certain words
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I know there's a lot of other questions out there that deal with this
I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.
I have a view passing on information from a database: def serve_article(request, id): served_article

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.