I have been working with SQL for a very long time, but this is the first time I've seen it.
I have a table contacts:
+------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| id | int(11) | YES | MUL | NULL | |
| client_id | varchar(191) | YES | MUL | NULL | |
| client_status | int(11) | YES | | NULL | |
| lastname | varchar(191) | YES | | NULL | |
| firstname | varchar(191) | YES | | NULL | |
| patronymic | varchar(191) | YES | | NULL | |
| date_of_birth | date | YES | MUL | NULL | |
| sex | int(11) | YES | | NULL | |
| state | int(11) | YES | MUL | NULL | |
| phone_mobile | varchar(191) | YES | MUL | NULL | |
| phone_home | varchar(191) | YES | | NULL | |
| adr_city_type | varchar(191) | YES | | NULL | |
| adr_city | varchar(191) | YES | | NULL | |
| adr_apt | varchar(191) | YES | | NULL | |
| adr_street_num | varchar(191) | YES | | NULL | |
| adr_street | varchar(191) | YES | | NULL | |
| adr_street_type | varchar(191) | YES | | NULL | |
| adr_district | varchar(191) | YES | | NULL | |
| adr_postcode | varchar(191) | YES | | NULL | |
| email | varchar(191) | YES | MUL | NULL | |
| comment | text | YES | | NULL | |
+------------------+--------------+------+-----+---------+-------+
I have a simple query:
select client_id, lastname, firstname, phone_mobile, email
from contacts
where `client_id`="8011000000000005263"
limit 1;
When I execute it, I get the following result:
Empty set (0.00 sec)
I know that this identifier is a database and I decided to experiment with the query, see the result below.
2.
mysql> select client_id, lastname, firstname, phone_mobile, email from contacts where `client_id` like "%8011000000000005263%" limit 1;
Empty set (1.74 sec)
3.
mysql> select client_id, lastname, firstname, phone_mobile, email from contacts whereclient_id=8011000000000005263 limit 1;
+-------------------+----------------------+-----------+---------------+-------+
| client_id | lastname | firstname | phone_mobile | email |
+-------------------+----------------------+-----------+---------------+-------+
| 8011000000000004655| OSTROVKAYA | YANA | +111111111111| NULL |
+-------------------+----------------------+-----------+---------------+-------+
1 row in set (0.68 sec)
4.
mysql> select client_id, lastname, firstname, phone_mobile, email from
contacts where `client_id`= 8011000000000005263;
234 rows in set (0.83 sec) - WTF ???
5.
mysql> select client_id, lastname, firstname, phone_mobile, email from
contacts use index (client_id) where `client_id`=8011000000000005263;
234 rows in set (0.90 sec) - WTF ???
6.
mysql> select client_id, lastname, firstname, phone_mobile, email from contacts use index (client_id) where client_id in (8011000000000005263) group by id_client;
234 rows in set (1.94 sec) - WTF ???
I want to provide an explanation for the last request:
mysql> explain select client_id, lastname, firstname, phone_mobile, email from contacts use index (client_id) where client_id in (8011000000000005263) group by id_client;
+----+-------------+--------------+------------+-------+---------------+-----------+---------+------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------------+-------+---------------+-----------+---------+------+---------+----------+-------------+
| 1 | SIMPLE | contacts | NULL | index | client_id | client_id | 576 | NULL | 1183745 | 10.00 | Using where |
+----+-------------+--------------+------------+-------+---------------+-----------+---------+------+---------+----------+-------------+
1 row in set, 3 warnings (0.00 sec)
I can not understand why a simple query is not executed correctly. And how do I get the right result.
Moreover, this request is placed on the MySQL server (((
When we will be do communicate with the auxiliary table, then the request hangs for 20-30 minutes.
To be fully aware of what is happening I will provide table indexes:
+--------------+------------+------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| contacts | 1 | id | 1 | id | A | 1177634 | NULL | NULL | YES | BTREE | | |
| contacts | 1 | client_id | 1 | client_id | A | 1136884 | NULL | NULL | YES | BTREE | | |
| contacts | 1 | combo | 1 | email | A | 194844 | NULL | NULL | YES | BTREE | | |
| contacts | 1 | combo | 2 | phone_mobile | A | 1165372 | NULL | NULL | YES | BTREE | | |
| contacts | 1 | combo | 3 | date_of_birth | A | 1081845 | NULL | NULL | YES | BTREE | | |
| contacts | 1 | combo | 4 | state | A | 1148369 | NULL | NULL | YES | BTREE | | |
| contacts | 1 | email | 1 | email | A | 197052 | NULL | NULL | YES | BTREE | | |
| contacts | 1 | phone_mobile | 1 | phone_mobile | A | 1127414 | NULL | NULL | YES | BTREE | | |
| contacts | 1 | state | 1 | state | A | 2 | NULL | NULL | YES | BTREE | | |
+--------------+------------+------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
9 rows in set (0.02 sec)
Please, could not experienced developers explain to me this phenomenon of the behavior of this language.
Thank you so much! All clean code :)
Related
Parent Table,
mysql> desc sattool_testing;
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| circuit_id | varchar(30) | NO | | NULL | |
| coff_id | varchar(100) | NO | | NULL | |
| result | int(11) | YES | | NULL | |
| result_details | text | NO | | NULL | |
| details | longtext | NO | | NULL | |
| reverse_response | varchar(100) | NO | | NULL | |
| start_date | datetime | NO | | NULL | |
| end_date | datetime | YES | | NULL | |
| Modules | varchar(100) | YES | | NULL | |
| rehit | datetime | YES | | NULL | |
| isAuto | tinyint(1) | NO | | 0 | |
+------------------+--------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)
1st Child Table,
mysql> desc sattool_desc;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| sattool_desc_id | bigint(20) | NO | PRI | NULL | auto_increment |
| ceinterface | varchar(50) | YES | | NULL | |
| cehostname | varchar(50) | YES | | NULL | |
| vprnno | varchar(50) | YES | | NULL | |
| policyname | varchar(50) | YES | | NULL | |
| cosno | varchar(10) | YES | | NULL | |
| peipaddress | varchar(17) | YES | | NULL | |
| router_type | varchar(5) | YES | | NULL | |
| sattool_testing_id | bigint(20) | YES | | NULL | |
| epipeid | varchar(20) | YES | | NULL | |
| cerouter | varchar(10) | YES | | NULL | |
| service_type | varchar(10) | YES | | NULL | |
| scope_of_manage | varchar(50) | YES | | NULL | |
| service_name | varchar(10) | YES | | NULL | |
| ce_vrf_name | varchar(150) | YES | | NULL | |
+--------------------+--------------+------+-----+---------+----------------+
15 rows in set (0.01 sec)
2nd Child Table (Contain multiple records against one parent table record),
mysql> desc sattool_error_log;
+----------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+-------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| service_id | varchar(30) | NO | | NULL | |
| coff_id | varchar(50) | NO | | NULL | |
| error_name | varchar(100) | NO | | NULL | |
| error_desc | text | NO | | NULL | |
| error_occurred | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| error_type | int(11) | YES | | NULL | |
| error_code | varchar(10) | YES | | NULL | |
| sattool_id | bigint(20) | YES | | 0 | |
| module_no | int(11) | YES | | 0 | |
+----------------+--------------+------+-----+-------------------+-----------------------------+
10 rows in set (0.00 sec)
SQL Query :-
SELECT GROUP_CONCAT(sattool_error_log.error_desc) AS err_desc, GROUP_CONCAT(sattool_error_log.error_type) AS err_type, sattool_testing.*, sattool_desc.service_type, sattool_desc.service_name, sattool_desc.scope_of_manage
FROM sattool_testing
LEFT JOIN sattool_desc ON sattool_testing.id = sattool_desc.sattool_testing_id
LEFT JOIN sattool_error_log ON sattool_testing.id = sattool_error_log.sattool_id
WHERE sattool_testing.isAuto = 1 GROUP BY sattool_testing.id ORDER BY sattool_testing.id DESC limit 100
Current Execution Time is (22.76 sec)
Explain Query :-
+----+-------------+-------------------+------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------------+------+---------------+------+---------+------+------+----------------------------------------------+
| 1 | SIMPLE | sattool_testing | ALL | NULL | NULL | NULL | NULL | 3578 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | sattool_desc | ALL | NULL | NULL | NULL | NULL | 4009 | |
| 1 | SIMPLE | sattool_error_log | ALL | NULL | NULL | NULL | NULL | 8904 | |
+----+-------------+-------------------+------+---------------+------+---------+------+------+----------------------------------------------+
3 rows in set (0.00 sec)
I want to increase speed to above query execution.
Please give me suggestion on that.
Thanks!!!
I have added index to the columns used in the join/where clauses.
Like :-
ALTER TABLE sattool_desc ADD INDEX sattool_testing_id (sattool_testing_id);
ALTER TABLE sattool_error_log ADD INDEX sattool_id (sattool_id);
ALTER TABLE sattool_testing ADD INDEX isAuto (isAuto);
Now the execution time is 100 rows in set (0.00 sec).
Thanks again.
im stuck with a query which take more than 13 secs to return output
i did create the indexes but the execution plan doesnt seem to use them. Below are some information regarding
Query
SELECT userinfo.username,userinfo.firstname,userinfo.lastname,userinfo.email,
radcheck.attribute,radcheck.value,radusergroup.groupname, userinfo.id,
userinfo.workphone,userinfo.homephone,
userinfo.mobilephone,userinfo.address, userinfo.zone,
userinfo.account_state,userinfo.device_owner,userinfo.link_type,userinfo.account_type
FROM userinfo
INNER JOIN radcheck ON userinfo.username = radcheck.username
INNER JOIN radusergroup ON userinfo.username = radusergroup.username
WHERE radcheck.attribute='Expiration' and
STR_TO_DATE(radcheck.value, '%d %M %Y') < CURDATE()
and radusergroup.groupname='Customer30M';
Explain output
+----+-------------+--------------+------+--------------------+-----------+---------+--------------------------------+------+-----------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+------+--------------------+-----------+---------+--------------------------------+------+-----------------------------------+
| 1 | SIMPLE | radusergroup | ref | username,groupname | groupname | 66 | const | 5 | Using where with pushed condition |
| 1 | SIMPLE | radcheck | ref | username,attribute | attribute | 34 | const | 9 | Using where |
| 1 | SIMPLE | userinfo | ref | username | username | 131 | ctradius.radusergroup.username | 10 | Using where |
+----+-------------+--------------+------+--------------------+-----------+---------+--------------------------------+------+-----------------------------------+
3 rows in set (0.00 sec)
Table Info
Table: radusergroup
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(64) | NO | MUL | | |
| groupname | varchar(64) | NO | MUL | | |
| priority | int(11) | NO | | 1 | |
+-----------+-------------+------+-----+---------+----------------+
radusergroup table Index
+--------------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| radusergroup | 0 | PRIMARY | 1 | id | A | 11292 | NULL | NULL | | BTREE | | |
| radusergroup | 1 | username | 1 | username | A | NULL | NULL | NULL | | BTREE | | |
| radusergroup | 1 | groupname | 1 | groupname | A | NULL | NULL | NULL | | BTREE | | |
| radusergroup | 1 | indexradusergroup | 1 | username | A | NULL | NULL | NULL | | BTREE | | |
| radusergroup | 1 | indexradusergroup | 2 | groupname | A | NULL | NULL | NULL | | BTREE | | |
Table : userinfo
---------------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+------------------+------+-----+---------------------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(128) | YES | MUL | NULL | |
| firstname | varchar(200) | YES | | NULL | |
| lastname | varchar(200) | YES | | NULL | |
| email | varchar(200) | YES | | NULL | |
| workphone | varchar(200) | YES | | NULL | |
| homephone | varchar(200) | YES | | NULL | |
| mobilephone | varchar(200) | YES | | NULL | |
| address | varchar(200) | YES | | NULL | |
| zone | varchar(20) | YES | | NULL | |
| account_state | varchar(10) | YES | | active | |
| change_commit | tinyint(1) | YES | | NULL | |
| link_type | varchar(8) | YES | | NULL | |
| account_type | varchar(255) | YES | | NULL | |
| device_owner | varchar(255) | YES | | NULL | |
| account_name | varchar(255) | YES | | NULL | |
| account_email | varchar(255) | YES | | NULL | |
| account_mobile | varchar(255) | YES | | NULL | |
| groupname | varchar(255) | YES | | NULL | |
+---------------------+------------------+------+-----+---------------------+----------------+
Indexes on userinfo
----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| userinfo | 0 | PRIMARY | 1 | id | A | 11282 | NULL | NULL | | BTREE | | |
| userinfo | 1 | username | 1 | username | A | NULL | NULL | NULL | YES | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
Table: Radcheck
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(64) | NO | MUL | | |
| attribute | varchar(32) | NO | MUL | | |
| op | char(2) | NO | | == | |
| value | varchar(253) | NO | MUL | | |
+-----------+------------------+------+-----+---------+----------------+
indexes on radcheck
+----------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| radcheck | 0 | PRIMARY | 1 | id | A | 33425 | NULL | NULL | | BTREE | | |
| radcheck | 1 | username | 1 | username | A | NULL | NULL | NULL | | BTREE | | |
| radcheck | 1 | value | 1 | value | A | NULL | NULL | NULL | | BTREE | | |
| radcheck | 1 | attribute | 1 | attribute | A | NULL | NULL | NULL | | BTREE | | |
The function invalidates the use of the index. Despite your cardinality showing 11k rows, the table scan ensues and it takes 13 seconds.
Though you have a join between Radcheck and userinfo, it is the STR_TO_DATE function in the where clause that kills the index use.
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
I am trying to optimize a MySQL select request:
SELECT * FROM `sales`
WHERE ((sales.private = false AND (sales.buyer_id IS NULL OR NOT sales.buyer_id=142)
AND (sales.merchand_id IS NULL OR NOT sales.merchand_id=142)
AND (sales.private_item = false) )
AND ((sales.buyer_id=32 OR sales.merchand_id=32)
AND (sales.admin=0 AND NOT sales.type IN ('book'))))
ORDER BY sales.created_at DESC, sales.id DESC LIMIT 0, 10;
The schema of the table is
mysql> SHOW columns from sales;
+------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| type | varchar(255) | YES | MUL | NULL | |
| buyer_id | int(11) | YES | MUL | NULL | |
| merchand_id | int(11) | YES | MUL | NULL | |
| private | tinyint(1) | YES | | 0 | |
| admin | tinyint(1) | YES | | 0 | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
| country_id | int(11) | YES | MUL | 0 | |
| private_item | tinyint(1) | YES | | 0 | |
+------------------------+--------------+------+-----+---------+----------------+
The indexes are:
mysql> show indexes from sales;
+-----------------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| sales | 0 | PRIMARY | 1 | id | A | 286509 | NULL | NULL | | BTREE | |
| sales | 1 | index_sales_on_type | 1 | type | A | 123 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_on_buyer_id | 1 | buyer_id | A | 40929 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_on_merchand_id | 1 | merchand_id | A | 40929 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_on_country_id | 1 | country_id | A | 6 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_on_type_and_country_id | 1 | type | A | 151 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_on_type_and_country_id | 2 | country_id | A | 428 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_viewed | 1 | buyer_id | A | 35813 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_viewed | 2 | merchand_id | A | 286509 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_viewed | 3 | private_item| A | 285009 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_viewed | 4 | admin | A | 285009 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_viewed | 5 | type | A | 285009 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_viewed | 6 | private | A | 285009 | NULL | NULL | YES | BTREE | |
| sales | 1 | index_sales_viewed | 7 | created_at | A | 285009 | NULL | NULL | YES | BTREE | |
+-------+------------+------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
When doing the query it uses the index_sales_on_type_and_country_id even if there is no country_id in the query...
The query takes 2.5 seconds with this index.
But when I use USE INDEX(index_sales_viewed) it goes down to 0.2 seconds.
Here is the EXPLAIN of the query:
+----+-------------+-----------------+------+----------------------------------------------+------+---------+------+--------+---------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------+------+----------------------------------------------+------+---------+------+--------+---------------------
| 1 | SIMPLE | sales | range | see bellow | index_sales_on_type_and_country_id | 258 | NULL | 208725 | Using where; Using filesort |
+----+-------------+-----------------+------+----------------------------------------------+------+---------+------+--------+---------------------
the possible keys are :
index_sales_on_type,
index_sales_on_buyer_id,
index_sales_on_merchand_id,
index_sales_on_type_and_country_id,
index_sales_public_recent_activity
Why doesn't MySQL use index_sales_viewed by default? Could there be a better index?
Thank you!
This is wrong use on NULL, please change all the column used in the index to be NOT NULL
refer this When to use NULL in MySQL tables
official documentation
If this column is NULL, there are no relevant indexes. In this case, you may be able to improve the performance of your query by examining the WHERE clause to check whether it refers to some column or columns that would be suitable for indexing. If so, create an appropriate index and check the query with EXPLAIN again
Mysql chosen index index_sales_on_type_and_country_id because you are not compare with NULL value
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;