Commit 8e268505 authored by Varun Gupta's avatar Varun Gupta

ORDER BY LIMIT

parent 77c63823
......@@ -1402,6 +1402,7 @@ The following specify which files/extra groups are read (specified before remain
Prohibit update of a VIEW, which does not contain a key
of the underlying table and the query uses a LIMIT clause
(usually get from GUI tools)
--use-sort-nest Enable the sort nest
--use-stat-tables=name
Specifies how to use system statistics tables. One of:
NEVER, COMPLEMENTARY, PREFERABLY,
......@@ -1781,6 +1782,7 @@ transaction-isolation REPEATABLE-READ
transaction-prealloc-size 4096
transaction-read-only FALSE
updatable-views-with-limit YES
use-sort-nest FALSE
use-stat-tables PREFERABLY_FOR_QUERIES
userstat FALSE
verbose TRUE
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
create database dbt3;
use dbt3;
--disable_query_log
--source include/dbt3_s001.inc
analyze table customer persistent for all;
analyze table orders persistent for all;
analyze table lineitem persistent for all;
analyze table nation persistent for all;
--enable_query_log
--echo # done to avoid filter for now
set optimizer_switch='rowid_filter=off';
set use_sort_nest=1;
--echo #
--echo # USING INDEXES FOR ORDERING
--echo #
--echo #
--echo # Using index scan on first table
--echo #
let $query= SELECT
c_nationkey, c_name, o_orderDate, o_totalprice, c_acctbal
FROM
orders, customer
WHERE
c_custkey= o_custkey
ORDER BY o_orderDATE DESC
LIMIT 5;
set use_sort_nest=1;
eval explain $query;
eval $query;
set use_sort_nest=0;
eval explain $query;
eval $query;
--echo #
--echo # Using range access for customer with index on (c), this does
--echo # the ordering
--echo #
alter table orders add key o_orderdate(o_orderDATE, o_custkey);
let $query= SELECT
o_custkey, c_name, o_orderDate, o_totalprice, c_acctbal
FROM
orders, customer
WHERE
c_custkey= o_custkey AND
o_orderDATE >='1997-07-30' and o_orderDATE <= '1998-07-30'
ORDER BY o_orderDATE, o_custkey DESC
LIMIT 5;
set use_sort_nest=1;
eval explain $query;
eval $query;
set use_sort_nest=0;
eval explain $query;
eval $query;
alter table orders drop key o_orderDate;
###############################################################################
--echo #
--echo # USING FILESORT
--echo #
--echo #
--echo # Filesort on first table (orders)
--echo #
let $query= SELECT
c_nationkey, c_name, o_orderDate, o_totalprice, c_acctbal, n_name
FROM
orders, customer, nation
WHERE
c_custkey= o_custkey AND c_nationkey=n_nationkey AND
o_orderDATE >='1997-01-30' and o_orderDATE <= '1997-12-31'
ORDER BY o_totalprice DESC
LIMIT 10;
set use_sort_nest=1;
eval explain $query;
eval $query;
set use_sort_nest=0;
eval explain $query;
eval $query;
--echo #
--echo # Filesort on first table (lineitem)
--echo #
show create table orders;
let $query= SELECT
l_extendedprice, o_orderkey, o_totalprice, l_shipDATE
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey AND
l_shipDATE >= '1996-01-01' AND l_shipDATE <= '1996-12-31'
ORDER BY l_extendedprice DESC
LIMIT 10;
set use_sort_nest=1;
eval explain $query;
eval $query;
set use_sort_nest=0;
eval explain $query;
eval $query;
###############################################################################
--echo #
--echo # Using Filesort with Sort Nest
--echo #
--echo #
--echo # FILESORT USING SORT-NEST on (orders, customer)
--echo #
let $query= SELECT
c_nationkey, c_name, o_orderDate, o_totalprice, c_acctbal, n_name
FROM
orders, customer, nation
WHERE
c_custkey= o_custkey AND c_nationkey=n_nationkey AND
o_orderDATE >='1997-07-01' and o_orderDATE <= '1997-07-31'
ORDER BY o_orderDATE DESC, c_acctbal DESC
LIMIT 10;
set use_sort_nest=1;
eval explain $query;
eval $query;
set use_sort_nest=0;
eval explain $query;
eval $query;
--echo #
--echo # Sort-nest on table (lineitem, customer)
--echo #
let $query= SELECT
c_acctbal, c_name, o_orderDate, l_extendedprice, l_orderkey
FROM
orders, customer, lineitem
WHERE
c_custkey= o_custkey
AND
l_orderkey = o_orderkey
AND
l_orderkey between 5500 AND 6000
AND
l_shipDATE >= '1997-01-01' and l_shipDATE <= '1998-08-10'
ORDER BY l_extendedprice DESC, c_acctbal DESC
LIMIT 20;
set use_sort_nest=1;
eval explain $query;
eval $query;
set use_sort_nest=0;
eval explain $query;
eval $query;
--echo ########################################################################
--echo #
--echo # Sort-nest on table (customer, orders, lineitem)
--echo #
let $query= SELECT
l_extendedprice, c_acctbal, o_totalprice, o_orderDate, l_orderkey
FROM
orders, customer, lineitem, nation
WHERE
c_custkey= o_custkey
AND
l_orderkey = o_orderkey
AND
n_nationkey = c_nationkey
AND
l_orderkey between 5500 AND 6000
AND
c_custkey between 1 and 10
ORDER BY
l_extendedprice DESC, c_acctbal DESC, o_totalprice DESC
LIMIT 20;
set use_sort_nest=1;
eval explain $query;
eval $query;
set use_sort_nest=0;
eval explain $query;
eval $query;
drop database dbt3;
This diff is collapsed.
--source include/have_innodb.inc
SET SESSION STORAGE_ENGINE='InnoDB';
--source sort_nest_dbt3.test
CREATE TABLE t1 (a int, b int, c int, KEY a_b (a,b), KEY a_c (a,c));
insert into t1 values (0,1,0), (0,2,0), (0,3,0), (0,4,0), (0,5,0), (0,6,0);
insert into t1 values (1,7,1), (1,8,1), (1,9,1), (1,10,1), (1,11,1), (1,12,1);
insert into t1 values (1,7,2), (1,8,2), (1,9,2), (1,10,2), (1,11,2), (1,12,2);
insert into t1 values (1,7,2), (1,8,2), (1,9,2), (1,10,2), (1,11,2), (1,12,2);
#
# index a_b should be used, no need for filesort
#
set use_sort_nest= 1;
select a,b,c from t1 where a=1 and c=2 order by b limit 5;
a b c
1 7 2
1 7 2
1 8 2
1 8 2
1 9 2
explain select a,b,c from t1 where a=1 and c=2 order by b limit 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a_b,a_c a_b 5 NULL 10 Using index condition; Using where
set use_sort_nest= 0;
explain select a,b,c from t1 where a=1 and c=2 order by b limit 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a_b,a_c a_b 5 NULL 18 Using where
drop table t1;
#
# Tests where Index(scan, ref or range access) satisfies the ORDERING
#
CREATE TABLE t1 (a int, b int, c int, KEY a_b (a,b), KEY a_c (a,c));
insert into t1 values (0,1,0), (0,2,0), (0,3,0), (0,4,0), (0,5,0), (0,6,0);
insert into t1 values (1,7,1), (1,8,1), (1,9,1), (1,10,1), (1,11,1), (1,12,1);
insert into t1 values (1,7,2), (1,8,2), (1,9,2), (1,10,2), (1,11,2), (1,12,2);
insert into t1 values (1,7,2), (1,8,2), (1,9,2), (1,10,2), (1,11,2), (1,12,2);
insert into t1 values (1,1,2);
# index key a_b, no need for filesort
set optimizer_trace=1;
set use_sort_nest=1;
select a,b,c from t1 where a=1 and c=2 order by b limit 10;
a b c
1 1 2
1 7 2
1 7 2
1 8 2
1 8 2
1 9 2
1 9 2
1 10 2
1 10 2
1 11 2
explain select a,b,c from t1 where a=1 and c=2 order by b limit 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a_b,a_c a_b 5 NULL 19 Using index condition; Using where
set use_sort_nest=0;
explain select a,b,c from t1 where a=1 and c=2 order by b limit 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a_b,a_c a_b 5 NULL 19 Using where
drop table t1;
CREATE TABLE t1(
a int NOT NULL,
b char NULL,
PRIMARY KEY(a)
);
INSERT INTO t1 VALUES (1,'a'), (2,'b'), (3,'c'), (4,'d');
#
# Should use index condition
#
set use_sort_nest= 1;
SELECT * FROM t1
WHERE a BETWEEN 1 and 2
ORDER BY a
LIMIT 2;
a b
1 a
2 b
EXPLAIN SELECT * FROM t1
WHERE a BETWEEN 1 and 2
ORDER BY a
LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition
set use_sort_nest= 0;
EXPLAIN SELECT * FROM t1
WHERE a BETWEEN 1 and 2
ORDER BY a
LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition
#
# Should not use index condition as ORDER by DESC is used
#
set use_sort_nest= 1;
EXPLAIN SELECT * FROM t1
WHERE a BETWEEN 1 and 2
ORDER BY a DESC
LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT * FROM t1
WHERE a BETWEEN 1 and 2
ORDER BY a DESC
LIMIT 2;
a b
2 b
1 a
set use_sort_nest= 0;
EXPLAIN SELECT * FROM t1
WHERE a BETWEEN 1 and 2
ORDER BY a DESC
LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
drop table t1;
create table t1(a int, b int, c int, key(a), key a_b(a,b));
insert into t1 values (0,1,0), (0,2,0), (0,3,0);
insert into t1 values (1,6,1), (1,7,1), (1,5,1);
insert into t1 values (2,8,2), (2,9,3), (2,10,4);
insert into t1 values (3,1,5);
create table t2(a int, b int, c int, key(b), key(c));
insert into t2 select a, b, c from t1;
#
# Testing using of Indexes on first non-const table
#
#
# Using range scan
#
set use_sort_nest= 1;
SELECT *
FROM
t1,t2
WHERE
t1.a=2 AND t2.b > 8 AND
t1.b=t2.b
ORDER BY t1.b LIMIT 10;
a b c a b c
2 9 3 2 9 3
2 10 4 2 10 4
EXPLAIN SELECT *
FROM
t1,t2
WHERE
t1.a=2 AND t2.b > 8 AND
t1.b=t2.b
ORDER BY t1.b LIMIT 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a,a_b a_b 10 NULL 2 Using index condition
1 SIMPLE t2 ref b b 5 test.t1.b 1
set use_sort_nest= 0;
EXPLAIN SELECT *
FROM
t1,t2
WHERE
t1.a=2 AND t2.b > 8 AND
t1.b=t2.b
ORDER BY t1.b LIMIT 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a,a_b a_b 10 NULL 2 Using index condition
1 SIMPLE t2 ref b b 5 test.t1.b 1
#
# Using ref access
#
set use_sort_nest= 1;
SELECT *
FROM
t1,t2
WHERE
t1.a=2 AND t2.c >= 1 AND
t1.b=t2.b
ORDER BY t1.b LIMIT 10;
a b c a b c
2 8 2 2 8 2
2 9 3 2 9 3
2 10 4 2 10 4
EXPLAIN SELECT *
FROM
t1,t2
WHERE
t1.a=2 AND t2.c >= 1 AND
t1.b=t2.b
ORDER BY t1.b LIMIT 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,a_b a_b 5 const 3 Using index condition; Using where
1 SIMPLE t2 ref b,c b 5 test.t1.b 1 Using where
set use_sort_nest= 0;
EXPLAIN SELECT *
FROM
t1,t2
WHERE
t1.a=2 AND t2.c >= 1 AND
t1.b=t2.b
ORDER BY t1.b LIMIT 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,a_b a_b 5 const 3 Using where
1 SIMPLE t2 ref b,c b 5 test.t1.b 1 Using where
drop table t1,t2;
# TESTS with INDEX HINTS
set use_sort_nest=1;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int,c int, key idx1(a), key idx2(a,b), key idx3(c));
insert into t1 select a,a,a from t0 where a <5;
analyze table t1 persistent for all;
#
# Index idx1 to be used for index scan
#
set use_sort_nest=1;
SELECT * from t1 where b > 0 order by t1.a limit 2;
a b c
1 1 1
2 2 2
EXPLAIN SELECT * from t1 where b > 0 order by t1.a limit 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx1 5 NULL 2 Using where
set use_sort_nest=0;
EXPLAIN SELECT * from t1 where b > 0 order by t1.a limit 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx1 5 NULL 2 Using where
#
# Index idx2 to be used for index scan(USE INDEX is used)
#
set use_sort_nest=1;
SELECT * from t1 USE INDEX(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
a b c
1 1 1
2 2 2
EXPLAIN SELECT * from t1 USE INDEX(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx2 10 NULL 2 Using where
set use_sort_nest=0;
EXPLAIN SELECT * from t1 USE INDEX(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx2 10 NULL 2 Using where
#
# Index idx2 to be used for index scan(USE INDEX for ORDER BY is used)
#
set use_sort_nest=1;
SELECT * from t1 USE INDEX FOR ORDER BY(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
a b c
1 1 1
2 2 2
EXPLAIN SELECT * from t1 USE INDEX FOR ORDER BY(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx2 10 NULL 2 Using where
set use_sort_nest=0;
EXPLAIN SELECT * from t1 USE INDEX FOR ORDER BY(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx2 10 NULL 2 Using where
#
# Use Filesort as idx3 does not resolve ORDER BY clause
#
set use_sort_nest=1;
SELECT * from t1 USE INDEX FOR ORDER BY(idx3)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
a b c
1 1 1
2 2 2
EXPLAIN SELECT * from t1 USE INDEX FOR ORDER BY(idx3)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using filesort
set use_sort_nest=0;
EXPLAIN SELECT * from t1 USE INDEX FOR ORDER BY(idx3)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using filesort
#
# Using index idx2 as idx1 is ignored
#
set use_sort_nest=1;
SELECT * from t1 IGNORE INDEX(idx1)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
a b c
1 1 1
2 2 2
EXPLAIN SELECT * from t1 IGNORE INDEX(idx1)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx2 10 NULL 2 Using where
set use_sort_nest=0;
EXPLAIN SELECT * from t1 IGNORE INDEX(idx1)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx2 10 NULL 2 Using where
#
# Use index idx2 for sorting, it is forced here
#
set use_sort_nest=1;
SELECT * from t1 FORCE INDEX(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
a b c
1 1 1
2 2 2
EXPLAIN SELECT * from t1 FORCE INDEX(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx2 10 NULL 2 Using where
set use_sort_nest=0;
EXPLAIN SELECT * from t1 FORCE INDEX(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx2 10 NULL 2 Using where
#
# Use FILESORT as idx3 cannot resolve ORDER BY clause
#
set use_sort_nest=1;
SELECT * from t1 FORCE INDEX FOR ORDER BY(idx3)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
a b c
1 1 1
2 2 2
EXPLAIN SELECT * from t1 FORCE INDEX FOR ORDER BY(idx3)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using filesort
set use_sort_nest=0;
EXPLAIN SELECT * from t1 FORCE INDEX FOR ORDER BY(idx3)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using filesort
drop table t0,t1;
CREATE TABLE t1 (a int, b int, c int, KEY a_b (a,b), KEY a_c (a,c));
insert into t1 values (0,1,0), (0,2,0), (0,3,0), (0,4,0), (0,5,0), (0,6,0);
insert into t1 values (1,7,1), (1,8,1), (1,9,1), (1,10,1), (1,11,1), (1,12,1);
insert into t1 values (1,7,2), (1,8,2), (1,9,2), (1,10,2), (1,11,2), (1,12,2);
insert into t1 values (1,7,2), (1,8,2), (1,9,2), (1,10,2), (1,11,2), (1,12,2);
--echo #
--echo # index a_b should be used, no need for filesort
--echo #
let $query= select a,b,c from t1 where a=1 and c=2 order by b limit 5;
set use_sort_nest= 1;
eval $query;
eval explain $query;
set use_sort_nest= 0;
eval explain $query;
drop table t1;
--echo #
--echo # Tests where Index(scan, ref or range access) satisfies the ORDERING
--echo #
CREATE TABLE t1 (a int, b int, c int, KEY a_b (a,b), KEY a_c (a,c));
insert into t1 values (0,1,0), (0,2,0), (0,3,0), (0,4,0), (0,5,0), (0,6,0);
insert into t1 values (1,7,1), (1,8,1), (1,9,1), (1,10,1), (1,11,1), (1,12,1);
insert into t1 values (1,7,2), (1,8,2), (1,9,2), (1,10,2), (1,11,2), (1,12,2);
insert into t1 values (1,7,2), (1,8,2), (1,9,2), (1,10,2), (1,11,2), (1,12,2);
insert into t1 values (1,1,2);
--echo # index key a_b, no need for filesort
let $query= select a,b,c from t1 where a=1 and c=2 order by b limit 10;
set optimizer_trace=1;
set use_sort_nest=1;
eval $query;
eval explain $query;
set use_sort_nest=0;
eval explain $query;
drop table t1;
CREATE TABLE t1(
a int NOT NULL,
b char NULL,
PRIMARY KEY(a)
);
INSERT INTO t1 VALUES (1,'a'), (2,'b'), (3,'c'), (4,'d');
--echo #
--echo # Should use index condition
--echo #
let $query= SELECT * FROM t1
WHERE a BETWEEN 1 and 2
ORDER BY a
LIMIT 2;
set use_sort_nest= 1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest= 0;
eval EXPLAIN $query;
--echo #
--echo # Should not use index condition as ORDER by DESC is used
--echo #
let $query= SELECT * FROM t1
WHERE a BETWEEN 1 and 2
ORDER BY a DESC
LIMIT 2;
set use_sort_nest= 1;
eval EXPLAIN $query;
eval $query;
set use_sort_nest= 0;
eval EXPLAIN $query;
drop table t1;
create table t1(a int, b int, c int, key(a), key a_b(a,b)); # 10 rows
insert into t1 values (0,1,0), (0,2,0), (0,3,0);
insert into t1 values (1,6,1), (1,7,1), (1,5,1);
insert into t1 values (2,8,2), (2,9,3), (2,10,4);
insert into t1 values (3,1,5);
create table t2(a int, b int, c int, key(b), key(c)); # 10 rows
insert into t2 select a, b, c from t1;
--echo #
--echo # Testing using of Indexes on first non-const table
--echo #
--echo #
--echo # Using range scan
--echo #
let $query= SELECT *
FROM
t1,t2
WHERE
t1.a=2 AND t2.b > 8 AND
t1.b=t2.b
ORDER BY t1.b LIMIT 10;
set use_sort_nest= 1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest= 0;
eval EXPLAIN $query;
--echo #
--echo # Using ref access
--echo #
let $query= SELECT *
FROM
t1,t2
WHERE
t1.a=2 AND t2.c >= 1 AND
t1.b=t2.b
ORDER BY t1.b LIMIT 10;
set use_sort_nest= 1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest= 0;
eval EXPLAIN $query;
drop table t1,t2;
--echo # TESTS with INDEX HINTS
set use_sort_nest=1;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int,c int, key idx1(a), key idx2(a,b), key idx3(c));
insert into t1 select a,a,a from t0 where a <5; # 5 rows
--disable_result_log
analyze table t1 persistent for all;
--enable_result_log
--echo #
--echo # Index idx1 to be used for index scan
--echo #
let $query= SELECT * from t1 where b > 0 order by t1.a limit 2;
set use_sort_nest=1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest=0;
eval EXPLAIN $query;
--echo #
--echo # Index idx2 to be used for index scan(USE INDEX is used)
--echo #
let $query= SELECT * from t1 USE INDEX(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
set use_sort_nest=1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest=0;
eval EXPLAIN $query;
--echo #
--echo # Index idx2 to be used for index scan(USE INDEX for ORDER BY is used)
--echo #
let $query= SELECT * from t1 USE INDEX FOR ORDER BY(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
set use_sort_nest=1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest=0;
eval EXPLAIN $query;
--echo #
--echo # Use Filesort as idx3 does not resolve ORDER BY clause
--echo #
let $query= SELECT * from t1 USE INDEX FOR ORDER BY(idx3)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
set use_sort_nest=1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest=0;
eval EXPLAIN $query;
--echo #
--echo # Using index idx2 as idx1 is ignored
--echo #
let $query= SELECT * from t1 IGNORE INDEX(idx1)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
set use_sort_nest=1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest=0;
eval EXPLAIN $query;
--echo #
--echo # Use index idx2 for sorting, it is forced here
--echo #
let $query= SELECT * from t1 FORCE INDEX(idx2)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
set use_sort_nest=1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest=0;
eval EXPLAIN $query;
--echo #
--echo # Use FILESORT as idx3 cannot resolve ORDER BY clause
--echo #
let $query= SELECT * from t1 FORCE INDEX FOR ORDER BY(idx3)
WHERE b > 0
ORDER BY t1.a LIMIT 2;
set use_sort_nest=1;
eval $query;
eval EXPLAIN $query;
set use_sort_nest=0;
eval EXPLAIN $query;
drop table t0,t1;
This diff is collapsed.
This diff is collapsed.
--echo #
--echo # Testing SORT-NEST with non-flattened Subqueries
--echo #
--echo #
--echo # Dependent subquery attached to table t3 outside the sort-nest(t1,t2)
--echo #
set use_sort_nest=1;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int);
insert into t1 select a,a from t0 where a <5; # 5 rows
create table t2 as select * from t1 where a < 5; # 5 rows
create table t3(a int, b int, c int);
insert into t3 select A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B; # 100 rows
create table t4(a int, b int, c int, key(b));
insert into t4 select A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B; # 100 rows
--echo # ref access inside the dependent subquery should be with sort-nest.b instead of t1.b
--echo # subquery is attached to table t3 which is outside the sort-nest
let $query= SELECT * FROM t1,t2,t3
WHERE t1.b=t2.b and
EXISTS (select 1 from t4 where t4.b=t1.b and t4.b < 4 group by t4.c having t3.b=max(t4.a))
ORDER BY t2.a desc,t1.a desc
LIMIT 5;
eval EXPLAIN $query;
eval EXPLAIN FORMAT=JSON $query;
eval $query;
--echo # same as above but exists to in transformation not allowed
--echo # subquery is attached to table t3 which is outside the sort-nest
set optimizer_switch='exists_to_in=off';
eval EXPLAIN $query;
eval EXPLAIN FORMAT=JSON $query;
eval $query;
set optimizer_switch=default;
drop table t0,t1,t2,t3,t4;
--echo # DEPENDENT SUBQUERIES
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (a int, b int);
insert into t1 select a,a from t0 where a <5;
create table t2 as select * from t1 where a < 5;
create table t3 as select (A.a + 10*B.a+C.a*100) as a, (A.a + 10*B.a+C.a*100) as b,
(A.a + 10*B.a+C.a*100) as c from t0 A, t0 B,t0 C; # 1000 rows
set optimizer_switch='exists_to_in=off';
--echo # sort-nest(t2,t1) and subquery should be attached to table ot1
let $query= select * from t2,t1,t3
where exists (select max(t3.a) from t3 t4 where t4.b=t1.b group by t4.c having t3.a= max(t4.a))
order by t2.a desc,t1.a desc limit 5;
eval explain $query;
eval explain format=json $query;
eval $query;
set optimizer_switch=default;
--echo # sort-nest(t2,t1) and subquery should be attached to table ot1 (same as above)
let $query= select * from t2,t1,t3
where t3.a in (select max(t4.a) from t3 t4 where t4.b=t1.b group by t4.c)
order by t2.a desc,t1.a desc limit 5;
eval explain $query;
eval explain format=json $query;
eval $query;
--echo # sort-nest(t2,t1) and dependent subquery in the select list
let $query= select (select t4.a from t3 t4 where t4.a > t1.b limit 1) as x, t2.b, t1.b, t3.a from t1,t2,t3
where t1.a = t2.a order by t2.b desc, t1.b desc limit 5;
eval explain $query;
eval explain format=json $query;
eval $query;
--echo #
--echo # sort-nest(t2,t1) and sort-nest fields substitution in the having clause of the subquery
--echo # after IN -> EXISTS transformation
--echo #
let $query= select * from t2,t1,t3 ot1
where t2.a+ot1.a in (select max(t3.a) from t3 where t3.b=t1.b group by t3.c)
order by t2.a desc,t1.a desc limit 5;
eval explain $query;
eval explain format=json $query;
eval $query;
drop table t0,t1,t2,t3;
......@@ -150,6 +150,7 @@ SET (SQL_SOURCE
sql_cte.cc
item_vers.cc
sql_sequence.cc sql_sequence.h ha_sequence.h
sql_sort_nest.cc
sql_tvc.cc sql_tvc.h
opt_split.cc
rowid_filter.cc rowid_filter.h
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -377,7 +377,8 @@ class Item_in_optimizer: public Item_bool_func
const char *func_name() const { return "<in_optimizer>"; }
Item_cache **get_cache() { return &cache; }
void keep_top_level_cache();
Item *transform(THD *thd, Item_transformer transformer, uchar *arg);
Item *transform(THD *thd, Item_transformer transformer,
bool transform_subquery, uchar *arg);
virtual Item *expr_cache_insert_transformer(THD *thd, uchar *unused);
bool is_expensive_processor(void *arg);
bool is_expensive();
......@@ -2997,7 +2998,8 @@ class Item_cond :public Item_bool_func
bool top_level() { return abort_on_null; }
void copy_andor_arguments(THD *thd, Item_cond *item);
bool walk(Item_processor processor, bool walk_subquery, void *arg);
Item *transform(THD *thd, Item_transformer transformer, uchar *arg);
Item *transform(THD *thd, Item_transformer transformer,
bool transform_subquery, uchar *arg);
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
void neg_arguments(THD *thd);
Item* propagate_equal_fields(THD *, const Context &, COND_EQUAL *);
......@@ -3006,7 +3008,7 @@ class Item_cond :public Item_bool_func
bool eval_not_null_tables(void *opt_arg);
bool find_not_null_fields(table_map allowed);
Item *build_clone(THD *thd);
bool excl_dep_on_table(table_map tab_map);
bool excl_dep_on_tables(table_map tab_map, bool multi_eq_checked);
bool excl_dep_on_grouping_fields(st_select_lex *sel);
};
......@@ -3179,7 +3181,8 @@ class Item_equal: public Item_bool_func
SARGABLE_PARAM **sargables);
SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
bool walk(Item_processor processor, bool walk_subquery, void *arg);
Item *transform(THD *thd, Item_transformer transformer, uchar *arg);
Item *transform(THD *thd, Item_transformer transformer,
bool transform_subquery, uchar *arg);
virtual void print(String *str, enum_query_type query_type);
const Type_handler *compare_type_handler() const { return m_compare_handler; }
CHARSET_INFO *compare_collation() const { return m_compare_collation; }
......@@ -3191,7 +3194,7 @@ class Item_equal: public Item_bool_func
This does not comply with the specification of the virtual method,
but Item_equal items are processed distinguishly anyway
*/
bool excl_dep_on_table(table_map tab_map)
bool excl_dep_on_tables(table_map tab_map, bool multi_eq_checked)
{
return used_tables() & tab_map;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -234,6 +234,9 @@ class Item_subselect :public Item_result_field,
virtual void reset_value_registration() {}
enum_parsing_place place() { return parsing_place; }
bool walk(Item_processor processor, bool walk_subquery, void *arg);
Item* transform(THD *thd, Item_transformer transformer,
bool transform_subquery, uchar *arg);
bool mark_as_eliminated_processor(void *arg);
bool eliminate_subselect_processor(void *arg);
bool set_fake_select_as_master_processor(void *arg);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment