performance - MySQL Speeding up left outer join / check for null queries -


the object of query rows table gender = f , username not exist in table b campid = xxxx. here query using success:

select `id`  pool    left join sent      on  pool.username = sent.username      , sent.campid = 'ya1lgfh9'  sent.username null    , pool.gender = 'f' 

the problem query takes on 9 minutes complete, pool table contains on 10 million rows , sent table going grow larger that. have created indexes many of columns including username , gender. however, mysql refuses use of indexes query. tried using force index. here indexes pool , output of explain query:

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | table | non_unique | key_name | seq_in_index | column_name | collation | cardinality | sub_part | packed | null | index_type | comment | +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | pool  |          0 | primary  |            1 | id          |         |     9326880 |     null | null   |      | btree      |         | | pool  |          1 | username |            1 | username    |         |     9326880 |     null | null   |      | btree      |         | | pool  |          1 | source   |            1 | source      |         |           6 |     null | null   |      | btree      |         | | pool  |          1 | gender   |            1 | gender      |         |           9 |     null | null   |      | btree      |         | | pool  |          1 | location |            1 | location    |         |       59030 |     null | null   |      | btree      |         | +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 6 rows in set (0.00 sec)  mysql> explain select `id` pool force index (username) left join sent on pool.username = sent.username , sent.campid = 'ya1lgfh9' sent.username null , pool.gender = 'f'; +----+-------------+-------+------+---------------+------+---------+------+---------+-------------------------+ | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows    |                   | +----+-------------+-------+------+---------------+------+---------+------+---------+-------------------------+ |  1 | simple      | pool  |  | null          | null | null    | null | 9326881 | using             | |  1 | simple      | sent  |  | null          | null | null    | null |     351 | using where; not exists | +----+-------------+-------+------+---------------+------+---------+------+---------+-------------------------+ 2 rows in set (0.00 sec) 

also, here indexes sent table:

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | table | non_unique | key_name | seq_in_index | column_name | collation | cardinality | sub_part | packed | null | index_type | comment | +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | sent  |          0 | primary  |            1 | primary_key |         |         351 |     null | null   |      | btree      |         | | sent  |          1 | username |            1 | username    |         |         351 |     null | null   |      | btree      |         | +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 2 rows in set (0.00 sec) 

you can see no indexes not being used , query takes extremely long. if has solution involves reworking query, please show me example of how using data structure won't have confusion of how implement , test. thank you.

first, original query correct in placement of everything... including camp. using left join pool sent, , pulling required equality such "camp" clause suggested converting inner join, requiring entry on both sides. leave had it.

you have index on user name on sent table, following.

build index on "sent" table on (campid, username) composite (ie: multiple key) index. way left join optimized both entries.

on "pool" table, try composite index on 3 fields of (gender, username, id ).

by doing this, can take advantage of not having go through actual pages of data encompass 10+ million records. since index has columns compare, doesn't have find actual record , @ columns, can use of index directly.

also, grins, added keyword "straight_join" tells mysql query show , don't try think me. many times, i've found improve query performance... on few have been given feedback has not helped.

select straight_join       p.id           pool p          left join sent s             on s.campid = 'ya1lgfh9'              , p.username = s.username                p.gender = 'f'       , s.username null  

all said, still going returning how many records out of 10+ million... if pool has 10+ million, , single camp has 5,000. still returning entire set.


Comments

Popular posts from this blog

django - How can I change user group without delete record -

java - Need to add SOAP security token -

java - EclipseLink JPA Object is not a known entity type -