简体   繁体   中英

High performance query to count many to many data

Requests Table:

requests
    +id (INT) AUTO_INCREMENT
    +title (VARCHAR)

Statuses Table:

statuses
    +id (INT) AUTO_INCREMENT
    +title (VARCHAR)

Relationship Table:

request_status (MANY TO MANY)
    +id (INT) AUTO_INCREMENT
    +request_id (INT) Foreign Key
    +status_id (INT)

I want to count only those requests whose current status_id is 2 . Current Request's Status (status_id) is the last one in the request_status table.

What will be the perfect high-performance query if data is around 1600k

Assuming that the latest status is the one with greatest id:

SELECT COUNT(*)
FROM request_status
WHERE status_id = 2
AND NOT EXISTS (
    SELECT 1
    FROM request_status AS x
    WHERE request_id = request_status.request_id
    AND id > request_status.id
)

Or this:

SELECT COUNT(*)
FROM (
    SELECT 1
    FROM request_status
    GROUP BY request_id
    HAVING MAX(CASE WHEN status_id = 2 THEN id END) = MAX(id)
) AS x

You will need some indexes. I suggest creating these ones:

KEY ix1 (request_id, status_id)
KEY ix2 (status_id,  request_id)
SELECT COUNT(*) FROM request_status WHERE status_id = 2;

如果我正确理解了您的问题,该方法应该最好地工作-即计算status_id等于2的对。

The schema for the relation table has several inefficiencies. I discuss them here .

But, instead, lets change the schema to make it even more efficient. Instead of 3 tables with a many:many mapping, have just one table:

CREATE TABLE requests (
    id ...,
    latest_status  ENUM('eating', 'sleeping', 'running'),
    all_statuses    SET('eating', 'sleeping', 'running'),
) ENGINE=InnoDB;

(Alternatively, you could use TINYINTs , but with different syntax.)

When the status for a given request changes, set latest_status and "or" the new status into all_statuses .

To check for latest being running : WHERE latest_status = 'running' .

Or, if using some numeric value: WHERE latest_status = 2 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM