-
Chandan Kunal authored
Description: The SELECT query with order-by clause gives unordered results if following conditions are met: 1. It should be a partitioned table with a composite prefix index. 2. WHERE clause should have an equality condition on the prefixed column. 3. Prefix column in index should be leading key. 4. Column used in ORDER-BY clause should be trailing key in the index. 5. Index should be chosen for handling for ORDER-BY clause. Ex: SELECT * FROM table WHERE prefixed_index_column = "constant" and order by "next_column_after_prefixed_index_column" ANALYSIS: While checking if an index could be used for sorting, optimizer picks an index if all the columns in the index before the ordering columns are constants for the execution (have equality conditions in the where clause). However this is not right when the columns are prefixed and the table is partitioned. To understand it better let's take following DDL: CREATE TABLE table( col1 int NOT NULL, col2 varchar(2) DEFAULT NULL, KEY col2_idx (data(1),id) ) DEFAULT CHARSET=utf8 /*!50100 PARTITION BY RANGE (id) (PARTITION p10 VALUES LESS THAN (10) , PARTITION p20 VALUES LESS THAN (20) ) */; Lets assume after inserting in table we have(records is in sorted order of partition column) partition p10 contains (4, 'ab'), (5, 'ab'), (5, 'ac'), (6, 'ab') and partition p20 contains (14, 'ab'), (15, 'ab'), (15, 'aa'), (16, 'ab') Now let's take following query for execution SELECT col1 FROM tutf8 WHERE col2 = 'ab' ORDER BY col1 ASC; In this query we have ORDER BY clause on 'col2' but the index is on 'col2' and 'col1'. So it is sorted accordingly. The first row to be out from both the partitions is "4", followed by "5" as they are lesser than "14". After this it will compare between ('ac', 5) and ('ab', 14). It will return 14 as 'ab' < 'ac'. The active partition now becomes p20. This will give out 15, 16 as 'ab', 'aa' are lesser than 'ac'. This will leave us with the final value which is 6. Hence final result of the query will be +----+ |col1| +----+ | 4 | | 5 | | 14 | | 15 | | 16 | | 6 | +----+ SOLUTION: test_if_order_by_key() calls new function is_prefix_index to determine whether prefix index is being used for sorting. If it is true, optimizer does not pick this index for ordering. Change-Id: I2715867ca3db537ba47ed82bf44a3f4e65949465
Chandan Kunal authoredDescription: The SELECT query with order-by clause gives unordered results if following conditions are met: 1. It should be a partitioned table with a composite prefix index. 2. WHERE clause should have an equality condition on the prefixed column. 3. Prefix column in index should be leading key. 4. Column used in ORDER-BY clause should be trailing key in the index. 5. Index should be chosen for handling for ORDER-BY clause. Ex: SELECT * FROM table WHERE prefixed_index_column = "constant" and order by "next_column_after_prefixed_index_column" ANALYSIS: While checking if an index could be used for sorting, optimizer picks an index if all the columns in the index before the ordering columns are constants for the execution (have equality conditions in the where clause). However this is not right when the columns are prefixed and the table is partitioned. To understand it better let's take following DDL: CREATE TABLE table( col1 int NOT NULL, col2 varchar(2) DEFAULT NULL, KEY col2_idx (data(1),id) ) DEFAULT CHARSET=utf8 /*!50100 PARTITION BY RANGE (id) (PARTITION p10 VALUES LESS THAN (10) , PARTITION p20 VALUES LESS THAN (20) ) */; Lets assume after inserting in table we have(records is in sorted order of partition column) partition p10 contains (4, 'ab'), (5, 'ab'), (5, 'ac'), (6, 'ab') and partition p20 contains (14, 'ab'), (15, 'ab'), (15, 'aa'), (16, 'ab') Now let's take following query for execution SELECT col1 FROM tutf8 WHERE col2 = 'ab' ORDER BY col1 ASC; In this query we have ORDER BY clause on 'col2' but the index is on 'col2' and 'col1'. So it is sorted accordingly. The first row to be out from both the partitions is "4", followed by "5" as they are lesser than "14". After this it will compare between ('ac', 5) and ('ab', 14). It will return 14 as 'ab' < 'ac'. The active partition now becomes p20. This will give out 15, 16 as 'ab', 'aa' are lesser than 'ac'. This will leave us with the final value which is 6. Hence final result of the query will be +----+ |col1| +----+ | 4 | | 5 | | 14 | | 15 | | 16 | | 6 | +----+ SOLUTION: test_if_order_by_key() calls new function is_prefix_index to determine whether prefix index is being used for sorting. If it is true, optimizer does not pick this index for ordering. Change-Id: I2715867ca3db537ba47ed82bf44a3f4e65949465
Loading