MySQL Recursive Select Query with unknown number of result set columns - mysql

I have been looking for a solution for the last few hours.
Here is some data to help explain this problem:
mysql> describe REGION_FEATURE;
+-----------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+------------------+------+-----+---------+----------------+
| ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
| REGION_ID | int(10) unsigned | NO | MUL | NULL | |
| NAME | varchar(255) | NO | | NULL | |
| FILENAME_NOMENCLATURE | varchar(255) | NO | | NULL | |
| CONFIG_FILE_TYPE | int(10) unsigned | NO | | NULL | |
| ITERATOR_GROUP | int(10) unsigned | NO | | NULL | |
+-----------------------+------------------+------+-----+---------+----------------+
mysql> select * from REGION_FEATURE;
+----+-----------+----------------+-----------------------+------------------+----------------+
| ID | REGION_ID | NAME | FILENAME_NOMENCLATURE | CONFIG_FILE_TYPE | ITERATOR_GROUP |
+----+-----------+----------------+-----------------------+------------------+----------------+
| 1 | 1 | MaxCpe01 | c01 | 0 | 1 |
| 2 | 1 | MaxCpe05 | c05 | 0 | 1 |
| 3 | 1 | PrivacyEnable | pe | 0 | 2 |
| 4 | 1 | PrivacyDisable | pd | 0 | 2 |
I need to write a query that will give the result in this way. I am expecting 4 rows, but the N number of combinations.
rows with the same interator_group(I_G) are not combined. In this example it's I_G =1 x I_G=2 but there can be N number of I_G
I_G=1 x I_G=n x I_G=...
MaxCpe01 | PrivacyEnable
MaxCpe01 | PrivacyDisable
MaxCpe05 | PrivacyEnable
MaxCpe05 | PrivacyDisable
Can anyone help?

Are you looking for something like this?
SELECT t1.name name1, t2.name name2
FROM region_feature t1 CROSS JOIN region_feature t2
WHERE t1.iterator_group <> t2.iterator_group
AND t1.id < t2.id
ORDER BY name1;
Output:
| NAME1 | NAME2 |
|----------|----------------|
| MaxCpe01 | PrivacyDisable |
| MaxCpe01 | PrivacyEnable |
| MaxCpe05 | PrivacyDisable |
| MaxCpe05 | PrivacyEnable |
Here is SQLFiddle demo

Related

How do I prevent combinations or permutaions in a joining table?

I have the following tables in MySQL Workbench:
MdV, MdV_has_Chain and Chain.
describe MdV
+------------+--------------+------+-----+-------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------+-------+
| MdVID | varchar(255) | NO | PRI | NULL | |
| Source | longtext | YES | | NULL | |
| Chains | int unsigned | NO | | 0 | |
| CampaignID | varchar(255) | NO | MUL | No_Campaign | |
+------------+--------------+------+-----+-------------+-------+
describe MdV_has_Chain
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| MdVID | varchar(255) | NO | PRI | NULL | |
| ChainID | varchar(255) | NO | PRI | NULL | |
| Chain_Num | int unsigned | NO | | NULL | |
+-----------+--------------+------+-----+---------+-------+
describe Chain
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| ChainID | varchar(255) | NO | PRI | NULL | |
| Positions | int unsigned | NO | | 0 | |
| VectorID | varchar(255) | NO | | NULL | |
+-----------+--------------+------+-----+---------+-------+
Here they are in the EER diagram.
Currently the tables of interest hold the following mock data:
select * from mdv;
+-------------+-----------------+--------+-------------+
| MdVID | Source | Chains | CampaignID |
+-------------+-----------------+--------+-------------+
| ITS058-M152 | | 1 | C7 |
| ITS058-M182 | | 2 | No_Campaign |
| ITS058-M244 | Rational Design | 1 | C16 |
| ITS058-M253 | Rational Design | 2 | C17 |
| ITS058-M258 | | 1 | No_Campaign |
| TEST | | 0 | No_Campaign |
+-------------+-----------------+--------+-------------+
select * from mdv_has_chain;
+-------------+------------+----------------+
| MdVID | ChainID | chain_position |
+-------------+------------+----------------+
| ITS058-M152 | ITS058-Ch1 | 1 |
| ITS058-M182 | ITS058-Ch2 | 1 |
| ITS058-M182 | ITS058-Ch3 | 2 |
| ITS058-M244 | ITS058-Ch4 | 1 |
| ITS058-M253 | Ch1 | 2 |
| ITS058-M253 | ITS058-Ch5 | 1 |
| ITS058-M258 | ITS058-Ch6 | 1 |
+-------------+------------+----------------+
select * from chain;
+------------+-----------+-------------+
| ChainID | Positions | VectorID |
+------------+-----------+-------------+
| Ch1 | 2 | T343 |
| ITS058-Ch1 | 7 | ITS058-V240 |
| ITS058-Ch2 | 7 | ITS058-V278 |
| ITS058-Ch3 | 1 | R208 |
| ITS058-Ch4 | 6 | ITS058-V352 |
| ITS058-Ch5 | 7 | ITS058-V361 |
| ITS058-Ch6 | 6 | ITS058-V366 |
+------------+-----------+-------------+
To see what chains each MdV has I used the following query:
select mdv.mdvid, group_concat(mdv_has_chain.chainid order by mdv_has_chain.chain_num) as chainid, group_concat(mdv_has_chain.chain_num order by mdv_has_chain.chain_num) as chain_position from mdv inner join mdv_has_chain on mdv.mdvid = mdv_has_chain.mdvid group by mdv_has_chain.mdvid
+-------------+-----------------------+----------------+
| mdvid | chainid | chain_position |
+-------------+-----------------------+----------------+
| ITS058-M152 | ITS058-Ch1 | 1 |
| ITS058-M182 | ITS058-Ch2,ITS058-Ch3 | 1,2 |
| ITS058-M244 | ITS058-Ch4 | 1 |
| ITS058-M253 | ITS058-Ch5,Ch1 | 1,2 |
| ITS058-M258 | ITS058-Ch6 | 1 |
+-------------+-----------------------+----------------+
I was wondering how I would prevent same ChainIds or a combination of them from being entered to a different MdVID? For example how would I prevent the following insert from working:
insert into mdv_has_chain (mdvid, chainid, chain_num) values ("TEST", "ITS058-Ch2", 2), ("TEST", "ITS058-Ch3", 1)
ITS058-M182 already has those ChainIDs, but in different positions. Note that an MdV can have from 1 to N chains. Similarly, how would I allow permutations of ChainIds at different positions, but prevent entries with the same positions from being entered? I don't intend on implementing both things at once. I just wanted to know how I would achieve either individually.
Thank you for you time. Any help is appreciated.

MySQL Query into single multi table join

End goal is to get tbl_output.output based on intent and slot attributes. I am currently handling it programmatically and would like to combine into one query if possible. I am open to restructuring any of the tables if needed.
SELECT id as intent_id FROM `tbl_intent` WHERE `name` = 'Car'
SELECT id as slot_id1 FROM `tbl_slot` WHERE `name` = '2018'
SELECT id as slot_id2 FROM `tbl_slot` WHERE `name` = 'Chevrolet'
SELECT id as slot_id3 FROM `tbl_slot` WHERE `name` = 'Corvette'
Example should return tbl_output ID 1 field "output".
SELECT
*,
output_id
FROM xref_intent_slot
LEFT JOIN tbl_slot slot1 ON xref_intent_slot.slot_id=slot1.id AND slot1.name='2018'
LEFT JOIN tbl_slot slot2 ON xref_intent_slot.slot_id=slot2.id AND slot2.name='Chevrolet'
LEFT JOIN tbl_slot slot3 ON xref_intent_slot.slot_id=slot3.id AND slot3.name='Corvette'
WHERE `intent_id` = (SELECT id from tbl_intent WHERE `name` = 'Car')
+----+-----------+-----------+---------+------+------+------+-----------+------+----------+-----------+
| id | output_id | intent_id | slot_id | id | name | id | name | id | name | output_id |
+----+-----------+-----------+---------+------+------+------+-----------+------+----------+-----------+
| 1 | 1 | 1 | 1 | 1 | 2018 | NULL | NULL | NULL | NULL | 1 |
| 2 | 1 | 1 | 2 | NULL | NULL | 2 | Chevrolet | NULL | NULL | 1 |
| 3 | 1 | 1 | 3 | NULL | NULL | NULL | NULL | 3 | Corvette | 1 |
| 4 | 2 | 1 | 4 | NULL | NULL | NULL | NULL | NULL | NULL | 2 |
| 5 | 2 | 1 | 2 | NULL | NULL | 2 | Chevrolet | NULL | NULL | 2 |
| 6 | 2 | 1 | 5 | NULL | NULL | NULL | NULL | NULL | NULL | 2 |
+----+-----------+-----------+---------+------+------+------+-----------+------+----------+-----------+
This should only return ID 1, 2, and 3 which is output_id 1. Then use that value to get the output from tbl_output?
Tables:
+-------------------+
| tbl_intent |
| tbl_output |
| tbl_slot |
| xref_intent_slot |
+-------------------+
Table: tbl_intent
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | MUL | NULL | |
+-------+--------------+------+-----+---------+----------------+
+----+------+
| id | name |
+----+------+
| 1 | Car |
+----+------+
Table: tbl_slot
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | MUL | NULL | |
+-------+--------------+------+-----+---------+----------------+
+----+-----------+
| id | name |
+----+-----------+
| 1 | 2018 |
| 2 | Chevrolet |
| 3 | Corvette |
| 4 | 2017 |
| 5 | Camaro |
+----+-----------+
Table: tbl_output
+--------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| output | text | NO | | NULL | |
+--------+---------+------+-----+---------+----------------+
+----+----------------+
| id | output |
+----+----------------+
| 1 | Found Corvette |
| 2 | Found Camaro |
+----+----------------+
Table: xref_intent_slot
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| output_id | int(11) | NO | | NULL | |
| intent_id | int(11) | NO | | NULL | |
| slot_id | int(11) | NO | | NULL | |
+-----------+---------+------+-----+---------+----------------+
+----+-----------+-----------+---------+
| id | output_id | intent_id | slot_id |
+----+-----------+-----------+---------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 2 |
| 3 | 1 | 1 | 3 |
| 4 | 2 | 1 | 4 |
| 5 | 2 | 1 | 2 |
| 6 | 2 | 1 | 5 |
+----+-----------+-----------+---------+
SELECT
`output`
FROM tbl_output
WHERE
id =
(
SELECT
output_id
FROM xref_intent_slot
LEFT JOIN tbl_slot slot1 ON xref_intent_slot.slot_id=slot1.id AND slot1.name='2018'
LEFT JOIN tbl_slot slot2 ON xref_intent_slot.slot_id=slot2.id AND slot2.name='Chevrolet'
LEFT JOIN tbl_slot slot3 ON xref_intent_slot.slot_id=slot3.id AND slot3.name='Corvette'
WHERE `intent_id` = (SELECT id from tbl_intent WHERE `name` = 'Car') AND
(slot1.name = '2018' OR
slot2.name = 'Chevrolet' OR
slot3.name = 'Corvette')
group by output_id
HAVING (count(output_id) = 3)
)
LIMIT 0,1

MySQL db join query

I am working with an Employee database in Mysql. My Db contains the following tables
mysql> describe edept;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| dept | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql>describe esal;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| basic | int(11) | NO | | NULL | |
| pf | int(11) | NO | | NULL | |
+-------+---------+------+-----+---------+-------+
mysql> describe edesig;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| desig | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql> select * from edetails inner join edept on edetails.dept=edept.id;
+----+--------+-----+------+-------+-------+----+----+------------------+
| id | name | age | dept | desig | basic | pf | id | dept |
+----+--------+-----+------+-------+-------+----+----+------------------+
| 1 | swetha | 21 | 3 | 2 | 2 | 2 | 3 | Business Process |
+----+--------+-----+------+-------+-------+----+----+------------------+
mysql> describe edetails;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
| dept | int(11) | NO | MUL | NULL | |
| desig | int(11) | YES | MUL | NULL | |
| basic | int(11) | NO | MUL | NULL | |
| pf | int(11) | NO | MUL | NULL | |
+-------+-------------+------+-----+---------+-------+
I have to get values for dept,desig,basic,pf from the tables edept.dept,edesig.desig,esal.basic,esal.pf respectively.
I used foreign keys for all the fields for which i have to retrieve values from other tables.And i tried a sample inner join query. but i got the output as follows:
mysql> select * from edetails inner join edept on edetails.dept=edept.id;
+----+--------+-----+------+-------+-------+----+----+------------------+
| id | name | age | dept | desig | basic | pf | id | dept |
+----+--------+-----+------+-------+-------+----+----+------------------+
| 1 | swetha | 21 | 3 | 2 | 2 | 2 | 3 | Business Process |
+----+--------+-----+------+-------+-------+----+----+------------------+
My edept table contains the following:
mysql> select * from edept;
+----+------------------+
| id | dept |
+----+------------------+
| 3 | Business Process |
+----+------------------+
How can i eliminate duplicate columns. i need the value "business process" in the dept field of the edept table
Try this::
select
edetails.id,
edetails.name,
edetails.age,
edetails.dept,
edesig.desig,
edetails.basic,
edetails.pf,
edept.dept
from edetails
inner join edept on edetails.dept=edept.id
INNER JOIN edesig on edesig.id=edetails.desig

MySQL JOIN and COUNT not coherent

I have these tables :
mysql> desc mod_asterisk_booking;
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| uid | int(10) unsigned | NO | | NULL | |
| server_id | int(10) unsigned | NO | | NULL | |
| date_call | datetime | NO | | NULL | |
| participants | int(10) unsigned | NO | | NULL | |
| ... |
+---------------+------------------+------+-----+---------+----------------+
mysql> desc mod_asterisk_servers;
+-------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(32) | NO | | NULL | |
| channels_capacity | int(10) unsigned | NO | | NULL | |
| ... |
+-------------------+------------------+------+-----+---------+----------------+
mysql> desc mod_asterisk_server_phones;
+------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| server_id | int(10) unsigned | NO | | NULL | |
| phone_number | varchar(15) | NO | | NULL | |
| phone_alias | varchar(15) | NO | | NULL | |
| extension | int(10) unsigned | NO | | NULL | |
| is_toll_free | tinyint(1) | NO | | 0 | |
| is_allow_foreign | tinyint(1) | NO | | 0 | |
+------------------+------------------+------+-----+---------+----------------+
The goal is to fetch a server (from mod_asterisk_servers) that has the enough channels available for a given date interval. This query
SELECT s.*,
s.`channels_capacity` - IFNULL(SUM(b.`participants`), 0) as 'channels_available'
FROM `mod_asterisk_servers` as s
LEFT JOIN `mod_asterisk_booking` as b ON (b.server_id=s.id AND (b.date_call BETWEEN '2011-07-30 15:15:00' AND '2011-07-30 17:15:00'))
GROUP BY s.id
ORDER BY 'channels_available' DESC;
could return something like :
+----+-------------+-----+------------------+--------------------+
| id | name | ... |channels_capacity | channels_available |
+----+-------------+-----+------------------+--------------------+
| 1 | Test server | ... | 150 | 140 |
+----+-------------+-----+------------------+--------------------+
Now, I'd like to add some columns to this query; notably the phone numbers associated with each server found. A phone number may have these combination :
local phone number (is_toll_free=0 AND is_allow_foreign=0)
toll free number, limited to a given region (is_toll_free=1 AND is_allow_foreign=0)
toll free number, allowing an "extended" region (is_toll_free=1 AND is_allow_foreign=1)
I tried this query
SELECT s.*,
s.`channels_capacity` - IFNULL(SUM(b.`participants`), 0) as 'channels_available',
count(p1.phone_number) as 'local_phones',
count(p2.phone_number) as 'toll_free_phones',
count(p3.phone_number) as 'allow_foreign_phones'
FROM `mod_asterisk_servers` as s
LEFT JOIN `mod_asterisk_booking` as b ON (b.server_id=s.id AND (b.date_call BETWEEN '2011-07-30 15:15:00' AND '2011-07-30 17:15:00'))
LEFT JOIN `mod_asterisk_server_phones` as p1 ON (p1.server_id=s.id AND p1.is_toll_free=0 AND p1.is_allow_foreign=0)
LEFT JOIN `mod_asterisk_server_phones` as p2 ON (p2.server_id=s.id AND p2.is_toll_free=1 AND p2.is_allow_foreign=0)
LEFT JOIN `mod_asterisk_server_phones` as p3 ON (p3.server_id=s.id AND p3.is_toll_free=1 AND p3.is_allow_foreign=1)
ORDER BY 'channels_available' DESC;
but it returns
+----+-------------+-----+-------------------+--------------------+--------------+------------------+----------------------+
| id | name | ... | channels_capacity | channels_available | local_phones | toll_free_phones | allow_foreign_phones |
+----+-------------+-----+-------------------+--------------------+--------------+------------------+----------------------+
| 1 | Test server | ... | 150 | 140 | 2 | 2 | 2 |
+----+-------------+-----+-------------------+--------------------+--------------+------------------+----------------------+
even though there are only three numbers for that server :
mysql> select * from mod_asterisk_server_phones where server_id = 1;
+----+-----------+----------------+-------------+-----------+--------------+------------------+
| id | server_id | phone_number | phone_alias | extension | is_toll_free | is_allow_foreign |
+----+-----------+----------------+-------------+-----------+--------------+------------------+
| 1 | 1 | XXX-XXX-XXXX | | XXXX | 0 | 0 |
| 2 | 1 | 1-800-XXX-XXXX | | XXXX | 1 | 0 |
| 3 | 1 | 1-800-XXX-XXXX | | XXXX | 1 | 1 |
+----+-----------+----------------+-------------+-----------+--------------+------------------+
Maybe someone with better understanding of SQL can help me figure out this one?
Thanks!
Try count(DISTINCT p1.phone_number) instead of count(p1.phone_number) (and the same for p2,p3). And don't forget the proper GROUP BY

Why doesn't mysql use my index?

I have two tables:
mysql> desc myps3t_gameusertrophyinfo;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| trophy_id | int(11) | NO | MUL | NULL | |
| date | datetime | NO | MUL | NULL | |
| date_read | varchar(100) | NO | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
5 rows in set (0.19 sec)
mysql> show index from myps3t_gameusertrophyinfo;
+---------------------------+------------+------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------------------------+------------+------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| myps3t_gameusertrophyinfo | 0 | PRIMARY | 1 | id | A | 4004589 | NULL | NULL | | BTREE | |
| myps3t_gameusertrophyinfo | 0 | user_id | 1 | user_id | A | 7686 | NULL | NULL | | BTREE | |
| myps3t_gameusertrophyinfo | 0 | user_id | 2 | trophy_id | A | 4004589 | NULL | NULL | | BTREE | |
| myps3t_gameusertrophyinfo | 1 | myps3t_gameusertrophyinfo_403f60f | 1 | user_id | A | 7686 | NULL | NULL | | BTREE | |
| myps3t_gameusertrophyinfo | 1 | myps3t_gameusertrophyinfo_61a683d8 | 1 | trophy_id | A | 22624 | NULL | NULL | | BTREE | |
| myps3t_gameusertrophyinfo | 1 | idx_gameusertrophyinfo_date | 1 | date | A | 4004589 | NULL | NULL | | BTREE | |
+---------------------------+------------+------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
7 rows in set (0.06 sec)
the other table:
mysql> desc myps3t_gametrophyinfo ;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| game_id | int(11) | NO | MUL | NULL | |
| name | varchar(500) | NO | | NULL | |
| desc | varchar(500) | NO | | NULL | |
| type | varchar(20) | NO | | NULL | |
| pic_url | varchar(200) | NO | | NULL | |
| desc_pt | varchar(500) | NO | | NULL | |
| name_pt | varchar(500) | NO | | NULL | |
| hidden_id | int(11) | NO | | NULL | |
| total_id | int(11) | NO | | NULL | |
| trophy_id | int(11) | NO | | NULL | |
| addon_id | int(11) | YES | | NULL | |
| points | double | NO | | 0 | |
| sony_id | int(11) | YES | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
14 rows in set (0.00 sec)
mysql> show index from myps3t_gametrophyinfo;
+-----------------------+------------+-------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------------+------------+-------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| myps3t_gametrophyinfo | 0 | PRIMARY | 1 | id | A | 25976 | NULL | NULL | | BTREE | |
| myps3t_gametrophyinfo | 1 | myps3t_gametrophyinfo_game_id | 1 | game_id | A | 764 | NULL | NULL | | BTREE | |
+-----------------------+------------+-------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
when i do this query:
mysql> explain select * from myps3t_gameusertrophyinfo a, myps3t_gametrophyinfo b where a.trophy_id = b.id and b.addon_id = 58; +----+-------------+-------+--------+--------------------------------------------------------------+---------+---------+-----------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------------------------------------------------+---------+---------+-----------------------------+---------+-------------+
| 1 | SIMPLE | a | ALL | myps3t_gameusertrophyinfo_61a683d8,myps3t_gameusertrophyinfo | NULL | NULL | NULL | 4004592 | |
| 1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 4 | fabriciols_ps3t.a.trophy_id | 1 | Using where |
+----+-------------+-------+--------+--------------------------------------------------------------+---------+---------+-----------------------------+---------+-------------+
2 rows in set (0.00 sec)
why mysql do not use my keys ?
this query take more than 30 seconds, the first table has 4milion records ...
-- edit --
for quasnoi
mysql> SELECT COUNT(*), COUNT(DISTINCT addon_id), SUM(addon_id = 58) FROM myps3t_gametrophyinfo;
+----------+--------------------------+--------------------+
| COUNT(*) | COUNT(DISTINCT addon_id) | SUM(addon_id = 58) |
+----------+--------------------------+--------------------+
| 25976 | 160 | 6 |
+----------+--------------------------+--------------------+
1 row in set (0.00 sec)
MySQL chooses a as a leading table and b as a driven table. It does use a PRIMARY KEY on b for the joins.
Create an index on myps3t_gametrophyinfo (addon_id), this way b will be more probably chosen as a leading table.
You can try
select * from
myps3t_gametrophyinfo b
STRAIGHT_JOIN myps3t_gameusertrophyinfo a ON (a.trophy_id = b.id)
WHERE b.addon_id = 58;
I would probably rewrite the query to try to get a more sane execution path. I think something like below is more likely to get you the performance you want and is more clear in what you are doing to a human reader
SELECT * FROM myps3t_gametrophyinfo a LEFT JOIN myps3t_gameusertrophyinfo b ON a.id = b.trophy_id WHERE a.addon_id=58;