I agree that my testing data is wrong, but
what I was wondering is why the query gets slow only when using join,
although without join it gives me lightning answer.

BTW, you gave me a big hint!
I didn't know about 'cardinality', so searched on the web with the
word 'cardinality',
which leads me to
http://dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html

This page says

"MySQL uses index cardinality estimates only in join optimization. If
some join is not optimized in the right way, you can try using ANALYZE
TABLE. In the few cases that ANALYZE TABLE doesn't produce values good
enough for your particular tables, you can use FORCE INDEX with your
queries to force the use of a particular index, or set the
max_seeks_for_key system variable to ensure that MySQL prefers index
lookups over table scans. "

So I added "FORCE INDEX" to my query like this.

SELECT *
FROM employees2skills e2s FORCE INDEX (mod_time )
 INNER JOIN companies c ON c.id = e2s.co_id
ORDER BY e2s.mod_time limit 5;
+----+-------------+-------+--------+---------------+----------+---------+----------------+---------+-------+
| id | select_type | table | type   | possible_keys | key      |
key_len | ref            | rows    | Extra |
+----+-------------+-------+--------+---------------+----------+---------+----------------+---------+-------+
|  1 | SIMPLE      | e2s   | index  | NULL          | mod_time | 4
 | NULL           | 1000638 |       |
|  1 | SIMPLE      | c     | eq_ref | PRIMARY       | PRIMARY  | 4
 | test.e2s.co_id |       1 |       |
+----+-------------+-------+--------+---------------+----------+---------+----------------+---------+-------+
2 rows in set (0.00 sec)

it's stunning...
So thanks to you, I can solve my problem, thanks you!
but I'm not quite sure what's going on.

Could you give me some hint please?


On 3/3/07, Filip Krejci <[EMAIL PROTECTED]> wrote:
It,s simple.

Look at cardinality on last two rows of statement 'show index from e2s'.

You have same cardinality on co_id and mod_time both.

My solution stands on the fact that mod_time will have much higher
selectivity in real data than co_id. (IMO)

So, I suppose that you have wrong testing data.

Filip


> Thank you for answering.
> I tried your suggestion and it's got fast, but still slow and
> could not get rid of "Using temporary; Using filesort".
>
> I don't understand why this simple query is so slow...
> 
------------------------------------------------------------------------------------------------------------
>
>
> mysql> ALTER TABLE employees2skills ADD INDEX(co_id, mod_time);
> Query OK, 1000000 rows affected (24.75 sec)
> Records: 1000000  Duplicates: 0  Warnings: 0
>
> mysql> analyze table employees2skills;
> +-----------------------+---------+----------+----------+
> | Table                 | Op      | Msg_type | Msg_text |
> +-----------------------+---------+----------+----------+
> | test.employees2skills | analyze | status   | OK       |
> +-----------------------+---------+----------+----------+
> 1 row in set (0.01 sec)
>
> mysql> show index from employees2skills;
> 
+------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
>
> | Table            | Non_unique | Key_name | Seq_in_index |
> Column_name | Collation | Cardinality | Sub_part | Packed | Null |
> Index_type | Comment |
> 
+------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
>
> | employees2skills |          0 | PRIMARY  |            1 | emp_id
> | A         |     1000638 |     NULL | NULL   |      | BTREE      |
>      |
> | employees2skills |          0 | PRIMARY  |            2 | skill_id
> | A         |     1000638 |     NULL | NULL   |      | BTREE      |
>      |
> | employees2skills |          1 | skill_id |            1 | skill_id
> | A         |          18 |     NULL | NULL   |      | BTREE      |
>      |
> | employees2skills |          1 | mod_time |            1 | mod_time
> | A         |          18 |     NULL | NULL   |      | BTREE      |
>      |
> | employees2skills |          1 | co_id    |            1 | co_id
> | A         |          18 |     NULL | NULL   |      | BTREE      |
>      |
> | employees2skills |          1 | co_id    |            2 | mod_time
> | A         |          18 |     NULL | NULL   |      | BTREE      |
>      |
> 
+------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
>
> 6 rows in set (0.00 sec)
>
> mysql> EXPLAIN SELECT * FROM employees2skills e2s INNER JOIN companies
> c ON c.id = e2s.co_id ORDER BY e2s.mod_time limit 5;
> 
+----+-------------+-------+-------+---------------+-------+---------+-----------+-------+----------------------------------------------+
>
> | id | select_type | table | type  | possible_keys | key   | key_len |
> ref       | rows  | Extra                                        |
> 
+----+-------------+-------+-------+---------------+-------+---------+-----------+-------+----------------------------------------------+
>
> |  1 | SIMPLE      | c     | index | PRIMARY       | name  | 62      |
> NULL      |     7 | Using index; Using temporary; Using filesort |
> |  1 | SIMPLE      | e2s   | ref   | co_id         | co_id | 4       |
> test.c.id | 55591 | Using index                                  |
> 
+----+-------------+-------+-------+---------------+-------+---------+-----------+-------+----------------------------------------------+
>
> 2 rows in set (0.00 sec)
>
> mysql> SELECT * FROM employees2skills e2s INNER JOIN companies c ON
> c.id = e2s.co_id ORDER BY e2s.mod_time limit 5;
> +--------+----------+-------+---------------------+----+-------+
> | emp_id | skill_id | co_id | mod_time            | id | name  |
> +--------+----------+-------+---------------------+----+-------+
> |    183 |        1 |     2 | 2007-03-03 17:59:35 |  2 | Apple |
> |    184 |        1 |     2 | 2007-03-03 17:59:35 |  2 | Apple |
> |    185 |        1 |     2 | 2007-03-03 17:59:35 |  2 | Apple |
> |    186 |        1 |     2 | 2007-03-03 17:59:35 |  2 | Apple |
> |    187 |        1 |     2 | 2007-03-03 17:59:35 |  2 | Apple |
> +--------+----------+-------+---------------------+----+-------+
> 5 rows in set (1.70 sec)
>
>
> On 3/3/07, Filip Krejci <[EMAIL PROTECTED]> wrote:
>> Hi,
>>
>> if your selectivity is very low, try to use multiple index on e2s(co_id,
>> mod_time) and force this index in query.
>>
>> Filip
>>
>>
>> >
>> > employees2skills:
>> > INSERT INTO employees2skills SELECT id, 1, 2, NOW() FROM employees;
>> > # Yes, 1000000 have same skill_id, co_id, and even mod_time.
>> > # selectivity is extreamly low
>> >
>>
>>
>> --
>> Filip Krejci <[EMAIL PROTECTED]>
>>
>> Vini, vidi, Linux!
>>
>> --
>> MySQL General Mailing List
>> For list archives: http://lists.mysql.com/mysql
>> To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]
>>
>>
>


--
Filip Krejci <[EMAIL PROTECTED]>

Microsoft gives you Windows... Linux gives you the whole house.

--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]



--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]

Reply via email to