简体   繁体   中英

Mysql Self-Join Performance

Let's say I have a table looks like this:

+----+----------+------------+-------+------+
| id | category |      state | A1code| val  |
+----+----------+------------+-------+------+
|  1 |        1 |    Florida | 13000 | 12   |
|  2 |        1 |    Florida | 13001 | 14   |
|  3 |        1 |    Florida | 13002 | 15   |
|  4 |        2 |    Florida | 13000 | 12   |
|  5 |        2 |    Florida | 13001 | 17   |
|  6 |        2 |    Florida | 13002 | 16   |
|  7 |        1 |  Calfornia | 13000 | 15   |
|  8 |        1 |  Calfornia | 13001 | 13   |
|  9 |        1 |  Calfornia | 13002 | 14   |
| 10 |        2 |  Calfornia | 13000 | 12   |
| 11 |        2 |  Calfornia | 13001 | 14   |
| 12 |        2 |  Calfornia | 13002 | 16   |
....
+----+----------+------------+------+

and I need to get the result in this fashion:

state, A1code, category1, category2
Florida,13000, 12,12
Florida,13001, 14,17
Florida,13002, 15,16
Calfornia,13000, 15,12
Calfornia,13001, 13,14
Calfornia,13002, 14,16
....

and im currently seeing the sql like this:

SELECT A.STATE, A.A1CODE, A.val AS category1, B.val AS category 2
FROM DUMMY_TABLE A
INNER JOIN DUMMY_TABLE B
USING (STATE,A1CODE)
WHERE A.category = 1 AND B.category = 2;

and with a table some 60k long, this query takes ~40secs to run on the computer.

now with a query like

SELECT A.STATE, A.A1CODE, A.val AS category1
FROM DUMMY_TABLE A
WHERE A.category = 1

running at less than 0.1sec, and what I want is just combining results from two category, there must be a faster way to do this?

(this problem comes when i try to port a db from MS ACCESS to MYSQL. the same query that took ~40s on MYSQL takes ~1sec to run in MS ACCESS.)

thanks in advance

You should avoid self joins on large table. It hampers performance a lot.

By the way, you should make index on column category. And see difference by query execution plan.

Try following variant

  SELECT A.STATE, A.A1CODE, A.val AS category1, B.val AS category 2
    FROM (select A.STATE A.A1code, A.val as category1 from DUMMY_TABLE A  where A.category = 1 ) as A
    LEFT JOIN DUMMY_TABLE B
    USING (STATE,A1CODE)
    WHERE B.category = 2  ;

It must be much faster.

But actualy that depend of 1) how much column you have in first query 2) do you have indexes on A1CODE,STATE or not.

so to speedup try

create index DUMMY_TABLE_get on DUMMY_TABLE(A1CODE,STATE);

There are also some methods to speedup this query upto 10-100ms, but they require add aditional fields/triggers. so no sence do that if you not gooing to get that query every minute.

Note, that 40sec is too much even for your request. Probably you have hire mysql administrator to tune your mysql server(use more RAM for joins, increase keybuffer etc)

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