mariadb/mysql-test/t/index_intersect.test

386 lines
10 KiB
Text
Raw Normal View History

--disable_warnings
DROP TABLE IF EXISTS t1,t2,t3,t4;
DROP DATABASE IF EXISTS world;
--enable_warnings
set names utf8;
CREATE DATABASE world;
use world;
--source include/world_schema.inc
--disable_query_log
--disable_result_log
--disable_warnings
--source include/world.inc
--enable_warnings
--enable_result_log
--enable_query_log
SELECT COUNT(*) FROM Country;
SELECT COUNT(*) FROM City;
SELECT COUNT(*) FROM CountryLanguage;
CREATE INDEX Name ON City(Name);
--disable_query_log
--disable_result_log
--disable_warnings
ANALYZE TABLE City;
--enable_warnings
--enable_result_log
--enable_query_log
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
SELECT COUNT(*) FROM City;
# The output of the next 6 queries tells us about selectivities
# of the conditions utilized in 4 queries following after them
SELECT COUNT(*) FROM City WHERE Name LIKE 'C%';
SELECT COUNT(*) FROM City WHERE Name LIKE 'M%';
SELECT COUNT(*) FROM City WHERE Population > 1000000;
SELECT COUNT(*) FROM City WHERE Population > 500000;
SELECT COUNT(*) FROM City WHERE Population > 300000;
SELECT COUNT(*) FROM City WHERE Population > 5000000;
# The pattern of the WHERE condition used in the following 4 queries is
# range(key1) AND range(key2)
# Varying values of the constants in the conjuncts of the condition
# we can get either an index intersection retrieval over key1 and key2
# or a range index scan for one of these indexes
EXPLAIN
SELECT * FROM City WHERE
Name LIKE 'C%' AND Population > 1000000;
EXPLAIN
SELECT * FROM City WHERE
Name LIKE 'M%' AND Population > 500000;
EXPLAIN
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 300000;
EXPLAIN
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 5000000;
# The following 8 queries check that
# the previous 4 plans are valid and return
# the correct results when executed
SELECT * FROM City USE INDEX ()
WHERE Name LIKE 'C%' AND Population > 1000000;
SELECT * FROM City
WHERE Name LIKE 'C%' AND Population > 1000000;
SELECT * FROM City USE INDEX ()
WHERE Name LIKE 'M%' AND Population > 500000;
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 500000;
SELECT * FROM City USE INDEX ()
WHERE Name LIKE 'M%' AND Population > 300000;
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 300000;
SELECT * FROM City USE INDEX ()
WHERE Name LIKE 'M%' AND Population > 5000000;
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 5000000;
# The output of the next 7 queries tells us about selectivities
# of the conditions utilized in 3 queries following after them
SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N';
SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J';
SELECT COUNT(*) FROM City WHERE Population > 1000000;
SELECT COUNT(*) FROM City WHERE Population > 700000;
SELECT COUNT(*) FROM City WHERE Population > 500000;
SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
SELECT COUNT(*) FROM City WHERE Country LIKE 'L%';
# The pattern of the WHERE condition used in the following 3 queries is
# range(key1) AND range(key2) AND range(key3)
# Varying values of the constants in the conjuncts of the condition
# we can get index intersection over different pairs of keys:
# over(key1,key2), over(key1,key3) and over(key2,key3)
EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'L%';
EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
# The following 6 queries check that
# the previous 3 plans are valid and return
# the correct results when executed
SELECT * FROM City USE INDEX ()
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
SELECT * FROM City
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
SELECT * FROM City USE INDEX ()
WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%';
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%';
SELECT * FROM City USE INDEX ()
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
# The output of the next 9 queries tells us about selectivities
# of the conditions utilized in 5 queries following after them
SELECT COUNT(*) FROM City WHERE ID BETWEEN 500 AND 999;
SELECT COUNT(*) FROM City WHERE ID BETWEEN 3500 AND 3999;
SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 1000;
SELECT COUNT(*) FROM City WHERE Population > 700000;
SELECT COUNT(*) FROM City WHERE Population > 1000000;
SELECT COUNT(*) FROM City WHERE Population > 300000;
SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
SELECT COUNT(*) FROM City WHERE Country LIKE 'A%';
SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z';
# The pattern of the WHERE condition used in the following 5 queries is
# range(key1) AND range(key2) AND range(key3)
# with key1 happens to be a primary key (it matters only for InnoDB)
# Varying values of the constants in the conjuncts of the condition
# we can get index intersection either over all three keys, or over
# different pairs, or a range sacn over one of these keys.
# Bear in mind that the condition (Country LIKE 'A%') is actually
# equivalent to the condition (Country BETWEEN 'A' AND 'B') for the
# tested instance the table City.
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%';
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%';
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%';
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000
AND Country BETWEEN 'S' AND 'Z';
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 1 AND 1000 AND Population > 700000
AND Country BETWEEN 'S' AND 'Z' ;
# The following 10 queries check that
# the previous 5 plans are valid and return
# the correct results when executed
SELECT * FROM City USE INDEX ()
WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%';
SELECT * FROM City
WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%';
SELECT * FROM City USE INDEX ()
WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%';
SELECT * FROM City
WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%';
SELECT * FROM City USE INDEX ()
WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%';
SELECT * FROM City
WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%';
SELECT * FROM City USE INDEX ()
WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000
AND Country BETWEEN 'S' AND 'Z';
SELECT * FROM City
WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000
AND Country BETWEEN 'S' AND 'Z';
SELECT * FROM City USE INDEX ()
WHERE ID BETWEEN 1 AND 1000 AND Population > 700000
AND Country BETWEEN 'S' AND 'Z' ;
SELECT * FROM City
WHERE ID BETWEEN 1 AND 1000 AND Population > 700000
AND Country BETWEEN 'S' AND 'Z' ;
SET SESSION sort_buffer_size = 2048;
# The following EXPLAIN command demonstrate that the execution plans
# may be different if sort_buffer_size is set to a small value
EXPLAIN
SELECT * FROM City WHERE
Name LIKE 'C%' AND Population > 1000000;
EXPLAIN
SELECT * FROM City WHERE
Name LIKE 'M%' AND Population > 500000;
EXPLAIN
SELECT * FROM City
WHERE Name LIKE 'C%' AND Population > 1000000 AND Country LIKE 'C%';
EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%';
EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%';
EXPLAIN
SELECT * FROM City
WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%';
#Yet the query themselves return the correct results in this case as well
SELECT * FROM City WHERE
Name LIKE 'C%' AND Population > 1000000;
SELECT * FROM City WHERE
Name LIKE 'M%' AND Population > 500000;
SELECT * FROM City
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%';
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
SELECT * FROM City
WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%';
SELECT * FROM City
WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%';
SET SESSION sort_buffer_size = default;
# Instead of the index on the column Country create two compound indexes
# including this column as the first component
DROP INDEX Country ON City;
CREATE INDEX CountryID ON City(Country,ID);
CREATE INDEX CountryName ON City(Country,Name);
--disable_query_log
--disable_result_log
--disable_warnings
ANALYZE TABLE City;
--enable_warnings
--enable_result_log
--enable_query_log
# Check that the first component of a compound index can be used for
# index intersection, even in the cases when we have a ref access
# for this component
EXPLAIN
SELECT * FROM City
WHERE Country LIKE 'M%' AND Population > 700000;
EXPLAIN
SELECT * FROM City
WHERE Country='CHN' AND Population > 1000000;
EXPLAIN
SELECT * FROM City
WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%';
# Check that the previous 3 plans return the right results when executed
SELECT * FROM City USE INDEX ()
WHERE Country LIKE 'M%' AND Population > 700000;
SELECT * FROM City
WHERE Country LIKE 'M%' AND Population > 700000;
SELECT * FROM City USE INDEX ()
WHERE Country='CHN' AND Population > 1000000;
SELECT * FROM City
WHERE Country='CHN' AND Population > 1000000;
SELECT * FROM City USE INDEX ()
WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%';
SELECT * FROM City
WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%';
DROP DATABASE world;
use test;
SET SESSION optimizer_switch='index_merge_sort_intersection=on';