diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index d990608f14e..9b3a584bbab 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -127,7 +127,7 @@ get_make_parallel_flag # implementation of SSL. --with-ssl=yes will first try system library # then the bundled one --with-ssl=system will use the system library. # We use bundled by default as this is guaranteed to work with Galera -SSL_LIBRARY=--with-ssl +SSL_LIBRARY=--with-ssl=bundled if [ "x$warning_mode" = "xpedantic" ]; then warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE" @@ -202,6 +202,7 @@ base_configs="$base_configs --with-extra-charsets=complex " base_configs="$base_configs --enable-thread-safe-client " base_configs="$base_configs --with-big-tables $maintainer_mode" base_configs="$base_configs --with-plugin-aria --with-aria-tmp-tables --with-plugin-s3=STATIC" +base_configs="$base_configs $SSL_LIBRARY" if test -d "$path/../cmd-line-utils/readline" then @@ -212,10 +213,10 @@ then fi max_plugins="--with-plugins=max" -max_no_embedded_configs="$SSL_LIBRARY $max_plugins" -max_no_qc_configs="$SSL_LIBRARY $max_plugins --without-query-cache" -max_configs="$SSL_LIBRARY $max_plugins --with-embedded-server --with-libevent --with-plugin-rocksdb=dynamic --with-plugin-test_sql_discovery=DYNAMIC --with-plugin-file_key_management=DYNAMIC --with-plugin-hashicorp_key_management=DYNAMIC" -all_configs="$SSL_LIBRARY $max_plugins --with-embedded-server --with-innodb_plugin --with-libevent" +max_no_embedded_configs="$max_plugins" +max_no_qc_configs="$max_plugins --without-query-cache" +max_configs="$max_plugins --with-embedded-server --with-libevent --with-plugin-rocksdb=dynamic --with-plugin-test_sql_discovery=DYNAMIC --with-plugin-file_key_management=DYNAMIC --with-plugin-hashicorp_key_management=DYNAMIC --with-plugin-auth_gssapi=DYNAMIC" +all_configs="$max_plugins --with-embedded-server --with-innodb_plugin --with-libevent" # # CPU and platform specific compilation flags. diff --git a/Docs/optimizer_costs.txt b/Docs/optimizer_costs.txt new file mode 100644 index 00000000000..dcb8bca7a23 --- /dev/null +++ b/Docs/optimizer_costs.txt @@ -0,0 +1,1309 @@ +This file is intended to explain some of the optimizer cost variables +in MariaDB 11.0 + +Background +========== + +Most timings has come from running: + +./check_costs.pl --rows=1000000 --socket=/tmp/mysql-dbug.sock --comment="--aria-pagecache-buffer-size=10G --innodb-buffer_pool_size=10G --key_buffer-size=1G --max-heap-table-size=10G" + +The MariaDB server is started with the options: +--aria-pagecache-buffer-size=10G --innodb-buffer_pool_size=10G --key_buffer-size=1G --max-heap-table-size=10G" + +- All costs are changed to be milliseconds for engine operations and + other calculations, like the WHERE clause. This is a big change from + before the patch that added this file where the basic cost was a + disk seek and one index read and we assumed they had the same cost. +- I am using Aria as the 'base' cost. This is because it caches all data, + which most other engines also would do. +- MyISAM cannot be used as 'base' as it does not cache row data (which gives + a high overhead when doing row lookups). +- Heap is in memory and a bit too special (no caching). +- InnoDB is a clustered engine where secondary indexes has to use + the clustered index to find a row (not a common case among storage engines). + +The old assumption in the optimzer has 'always' been that +1 cost = 1 seek = 1 index = 1 row lookup = 0.10ms. +However 1 seek != 1 index or row look and this has not been reflected in +most other cost. +This document is the base of changing things so that 1 cost = 1ms. + + +Setup +===== + +All timings are calculated based on result from this computer: +CPU: Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz +Memory: 256G +Disk: Samsum SSD 860 (not really relevant in this case) +Rows in tests: 1M Each test is run 3 times +(one test to cache the data and 2 runs of which we take the average). + +The assumption is that other computers will have somewhat proportional +timings. The timings are done with all data in memory (except MyISAM rows). +This is reflected in the costs for the test by setting +optimizer_disk_read_ratio=0. + +Note that even on a single Linux computer without any notable tasks +the run time vary a bit from run to run (up to 4%), so the numbers in +this document cannot be repeated exactly but should be good enough for +the optimizer. + +Timings for disk accesses on other system can be changed by setting +optimizer_disk_read_cost (usec / 4092 bytes) to match the read speed. + +Default values for check_costs.pl: +optimizer_disk_read_ratio= 0 Everything is cached +SCAN_LOOKUP_COST=1 Cost modifier for scan (for end user) +set @@optimizer_switch='index_condition_pushdown=off'"; + + +ROW_COPY_COST and KEY_COPY_COST +=============================== + +Regarding ROW_COPY_COST: +When calulating cost of fetching a row, we have two alternativ cost +parts (in addition to other costs): +scanning: rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST) +rnd_pos: rows * (ROW_LOOKUP_COST + ROW_COPY_COST) + +In theory we could remove ROW_COPY_COST and just move the cost +to the two other variables. However, in the future there may reason +to be able to modif row_copy_cost per table depending on number and type +of fields (A table of 1000 fields should have a higher row copy cost than +a table with 1 field). Because of this, I prefer to keep ROW_COPY_COST +around for now. + +Regarding KEY_COPY_COST: +When calulating cost of fetching a key we have as part of the cost: +keyread_time: rows * KEY_COPY_COST + ranges * KEY_LOOKUP_COST + + (rows-ranges) * KEY_NEXT_FIND_COST +key_scan_time: rows * (KEY_NEXT_FIND_COST + KEY_COPY_COST) + +We could remove KEY_COPY_COST by adding it to KEY_LOOKUP_COST and +KEY_NEXT_FIND_COST but I prefer to keep it with the same argument as +for ROW_COPY_COST. + +The reation between KEY_COPY_COST / (KEY_NEXT_FIND_COST + KEY_COPY_COST) +is assumed to be 0.1577 (See analyze in the appendix) + +There is a relationship between the above costs in that for a clustered +index the cost is calculated as ha_keyread_time() + ROW_COPY_COST. + + +Preramble +========= + +I tried first to use performance schema to get costs, but I was not +successful as all timings I got for tables showed the total time +executing the statement, not the timing for doing the actual reads. +Also the overhead of performance schema affected the results + +With --performance-schema=on + +MariaDB [test]> select sum(1) from seq_1_to_100000000; ++-----------+ +| sum(1) | ++-----------+ +| 100000000 | ++-----------+ +1 row in set (4.950 sec) + +Performance schema overhead: 30.1% + +With: +UPDATE performance_schema.setup_consumers SET ENABLED = 'YES'; +UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES'; + +Flush with: +CALL sys.ps_truncate_all_tables(FALSE); + +Performance schema overhead now: 32.9% + +Timings from: +select * from events_statements_current where thread_id=80; + +MariaDB [test]> select 885402302809000-884884140290000; ++---------------------------------+ +| 885402302809000-884884140290000 | ++---------------------------------+ +| 518162519000 | ++---------------------------------+ +-> Need to divide by 1000000000000.0 to get seconds + +As seen above, the above gives the total statement time not the time +spent to access the tables. + +In the end, I dediced to use analyze to find out the cost of the table +actions: + +For example: Finding out table scan timing (and thus costs): + +analyze format=json select sum(1) from seq_1_to_100000000; +r_table_time_ms": 1189.239022 + + +Calculating 'optimizer_where_cost' +================================== + +To make the WHERE cost reasonble (not too low) we are assuming there is +2 simple conditions in the default 'WHERE clause' + +MariaDB [test]> select benchmark(100000000,l_commitDate >= '2000-01-01' and l_tax >= 0.0) from test.check_costs limit 1; ++--------------------------------------------------------------------+ +| benchmark(100000000,l_commitDate >= '2000-01-01' and l_tax >= 0.0) | ++--------------------------------------------------------------------+ +| 0 | ++--------------------------------------------------------------------+ +1 row in set (3.198 sec) + +Time of where in seconds: 3.198 / 100000000 (100,000,000) + +Verification: + +select sum(1) from seq_1_to_100000000 where seq>=0.0 and seq>=-1.0; ++-----------+ +| sum(1) | ++-----------+ +| 100000000 | ++-----------+ +1 row in set (8.564 sec) + +MariaDB [test]> select sum(1) from seq_1_to_100000000; ++-----------+ +| sum(1) | ++-----------+ +| 100000000 | ++-----------+ +1 row in set (5.162 sec) + +Time of where= (8.564-5.162)/100000000 = 3.402/100000000 (100,000,000) +(Result good enough, as sligthly different computations) + +check_costs.pl comes provides the numbers when using heap tables and 1M rows: + +simple where: 118.689 ms +complex where: 138.474 ms +no where: 83.699 ms + +Which gives for simple where: +(118.689-83.699)/1000 = 0.034990000000000007 ms +Which is in the same ballpark. + +We use the result from the select benchmark run as this has least overhead +and is easiest to repeat and verify in a test. +Which gives: +optimizer_where_cost= 0.032 ms / WHERE. + + +HEAP TABLE SCAN & ROW_COPY_COST +=============================== + +We start with heap as all rows are in memory and we don't have to take +disk reads into account. + +select sum(l_partkey) from test.check_costs +table_scan ms: 10.02078736 +rows: 1000000 + +Cost should be 10.02078736 (scan cost) + 32 (where cost) + +cost= scan_time() * optimizer_cache_cost * SCAN_LOOKUP_COST + + TABLE_SCAN_SETUP_COST + + records * (ROW_COPY_COST + ROW_LOOKUP_COST + WHERE_COMPARE_COST); + +=> +We are ignoring TABLE_SCAN_SETUP (which is just to prefer index lookup on small +tables). +We can also ignore records * WHERE_COMPARE_COST as we don't have that +in the above calcuated 'ms'. +row_costs= (ROW_COPY_COST + ROW_LOOKUP_COST) + +cost= scan_time() * 1 * 1 + + 1000000.0 * (row_costs) +=> +cost= time_per_row*1000000 + row_costs * 1000000; +=> +time_per_row+row_cost= cost/1000000 + +Let's assume that for heap, finding the next row is 80 % of the time and +copying the row (a memcmp) to upper level is then 20 %. +(This is not really important, we could put everthing in heap_scan_time, +but it's good to have split the data as it gives us more options to +experiment later). + +row_lookup_cost= 10.02078736/1000000*0.8 = 8.0166298880000005e-06 +row_copy_cost= 10.02078736/1000000*0.2 = 2.0041574720000001e-06 + +Conclusion: +heap_scan_time= 8.0166e-06 +row_copy_cost= 2.0042e-06 + +Heap doesn't support key only read, so key_copy_cost is not relevant for it. + + +HEAP INDEX SCAN +=============== + +select count(*) from test.check_costs_heap force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0 +index_scan time: 79.7286117 ms + +Index scan on heap tables can only happen with binary trees. +l_supp_key is using a binary tree. + +cost= (ranges + rows + 1) * BTREE_KEY_NEXT_FIND_COST + rows * row_copy_cost= +(for large number of rows): +rows * (BTREE_KEY_NEXT_FIND_COST + row_copy_cost) + +BTREE_KEY_NEXT_FIND_COST= cost/rows - row_copy_cost = +79.7286117/1000000- 2.334e-06= 0.0000773946117 + + +HEAP EQ_REF +=========== + +select straight_join count(*) from seq_1_to_1000000,test.check_costs_heap where seq=l_linenumber +eq_ref_index_join time: 175.874165 of which 12.57 is from seq_1_to_1000000 + +Note: This is 34% of the cost of an Aria table with index lookup and + 20% of an Aria table with full key+row lookup. + +cost= rows * (key_lookup_cost + row_copy_cost) +key_lookup_cost= cost/rows - key_copy_cost = +(175.874165-12.57)/1000000 - 2.334e-06 = 0.00016097016500000002 + + +HEAP EQ_REF on binary tree index +================================ + +select straight_join count(*) from seq_1_to_1000000,test.check_costs_heap where seq=l_extra and l_partkey >= 0 +eq_ref_join time: 241.350539 ms of which 12.57 is from seq_1_to_1000000 + +rows * (tree_find_cost() + row_copy_cost) = + +tree_find_cost()= cost/rows - row_copy_cost = + +(241.350539-12.57)/1000000 - 2.334e-06= 0.000226446539 + +tree_find_cost() is defined as key_compare_cost * log2(table_rows) +-> +key_compare_cost= 0.000226446539/log2(1000000) = 0.000011361200108882259; + + +SEQUENCE SCAN +============= + +analyze format=json select sum(seq+1) from seq_1_to_1000000; +r_table_time_ms: 12.47830611 + +Note that for sequence index and table scan is the same thing. +We need to have a row_copy/key_copy cost as this is used when doing +an key lookup for sequence. Setting these to 50% of the full cost +should be sufficent for now. + +Calculation sequence_scan_cost: + +When ignoring reading from this, the cost of table scan is: +rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST) + +The cost of key scan is: +ranges * KEY_LOOKUP_COST + (rows - ranges) * KEY_NEXT_FIND_COST + +rows * KEY_COPY_COST; + +As there is no search after first key for sequence, we can set +KEY_LOOKUP_COST = KEY_NEXT_FIND_COST. + +This gives us: + +r_table_time_ms = (ROW_NEXT_FIND_COST + ROW_COPY_COST) = + (KEY_NEXT_FIND_COST + KEY_COPY_COST) * 1000000; + +-> +ROW_NEXT_FIND_COST= ROW_COPY_COST = KEY_LOOKUP_COST + KEY_COPY_COST= +12.47830611/1000000/2 = 0.0000062391530550 + + +HEAP KEY LOOKUP +=============== + +We can use this code to find the timings of a index read in a table: + +analyze format=json select straight_join count(*) from seq_1_to_1000000,check_costs where seq=l_orderkey + +"query_block": { + "select_id": 1, + "r_loops": 1, + "r_total_time_ms": 420.5083447, + "table": { + "table_name": "seq_1_to_1000000", + "access_type": "index", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "8", + "used_key_parts": ["seq"], + "r_loops": 1, + "rows": 1000000, + "r_rows": 1000000, + "r_table_time_ms": 12.47830611, + "r_other_time_ms": 44.0671283, + "filtered": 100, + "r_filtered": 100, + "using_index": true + }, + "table": { + "table_name": "check_costs", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["test.seq_1_to_1000000.seq"], + "r_loops": 1000000, + "rows": 1, + "r_rows": 1, + "r_table_time_ms": 160 + "filtered": 100, + "r_filtered": 100, + "attached_condition": "seq_1_to_1000000.seq = check_costs.l_orderkey" + } + } + +This gives the time for a key lookup on hash key as: +160/10000000 - row_copy_cost = +160/1000000.0 - 2.0042e-06 = 0.00015799580000000002 + + +ARIA TABLE SCAN +=============== +(page format, all rows are cached) + +table_scan ms: 107.315698 + +Cost is calculated as: + +blocks= stats.data_file_length / stats.block_size) = 122888192/4096= 30002 +engine_blocks (8192 is block size in Aria) = 15001 + +cost= blocks * avg_io_cost() * + optimizer_cache_cost * SCAN_LOOKUP_COST + + engine_blocks * INDEX_BLOCK_COPY_COST + + TABLE_SCAN_SETUP_COST + + records * (ROW_NEXT_FIND_COST + ROW_COPY_COST)); + +When all is in memory (optimizer_cache_cost= 0) we get: + +cost= blocks * INDEX_BLOCK_COPY_COST + + TABLE_SCAN_SETUP_COST + + records * (ROW_NEXT_FIND_COST + ROW_COPY_COST)); + +To calculate INDEX_BLOCK_COPY_COST I added a temporary tracker in +ma_pagecache.cc::pagecache_read() and did run the same query. +I got the following data: +{counter = 17755, sum = 1890559} +Which give me the time for copying a block to: +1000.0*1890559/sys_timer_info.cycles.frequency/17755 = 3.558138826971332e-05 ms +And thus INDEX_BLOCK_COPY_COST= 0.035600 + +Replacing known constants (and ignore TABLE_SCAN_SETUP_COST): +cost= 107.315698 = 15001 * 3.56e-5 + 1000000 * aria_row_copy_costs; + +aria_row_copy_costs= (107.315698 - (15001 * 3.56e-5))/1000000 = +0.0001067816624 + +As ROW_COPY_COST/ROW_NEXT_FIND_COST= 0.57 (See appendex) + +ROW_COPY_COST= 0.0001067816624 * 0.57 = 0.000060865547560 +ROW_NEXT_FIND_COST= 0.0001067816624 * 0.43 = 0.000045916114832 + + +Aria, INDEX SCAN +================ + +Finding out cost of reading X keys from an index (no row lookup) in Aria. + +Query: select count(*) from test.check_costs_aria force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0 +Table access time: ms: 98.1427158 + +blocks= index_size/IO_SIZE = +(rows * tot_key_length / INDEX_BLOCK_FILL_FACTOR) / IO_SIZE +-> +1000000 * 19 / 0.75/ 4096 = 6184 +engine_blocks (block_size 8192) = 6184/2 = 3092 +(Range optimzer had calculated 3085) + +keyread_time= blocks * avg_io_cost() * cache + engine_blocks * INDEX_BLOCK_COPY_COST + rows * (KEY_NEXT_FIND_COST + KEY_COPY_COST); += engine_blocks * INDEX_BLOCK_COPY_COST + rows * KEY_NEXT_FIND_COST= + 3092 * 3.56e-05 + 1000000 * (KEY_NEXT_FIND_COST + KEY_COPY_COST) +-> +KEY_NEXT_FIND_COST + KEY_COPY_COST= (98.1427158 - 3092 * 3.56e-05)/1000000 = +0.0000980326406; + +KEY_COPY_COST= 0.0000980326406 * 0.16 = 0.000015685222496 +KEY_NEXT_FIND_COST= 0.0000980326406 * 0.84 = 0.000082347418104 + + +Aria, RANGE SCAN (scan index, fetch a row for each index entry) +=============================================================== + +Query: +select sum(l_orderkey) from test.check_costs_aria force index(l_suppkey) where l_suppkey >= 0 and l_partkey >=0 +range_scan ms: 309.7620909 + +cost= keyread_time + rnd_pos_time. +keyread_time is as above in index scan, but whithout KEY_COPY_COST: +keyread_time= 98.1427158 - KEY_COPY_COST * 1000000= +98.1427158 - 0.000015685222496 * 1000000= 82.457493304000000; +rnd_pos_time= 309.7620909 - 82.457493304000000 = 227.304597596000000 + +rnd_pos_time() = io_cost + engine_mem_cost + + rows * (ROW_LOOKUP_COST + ROW_COPY_COST) = +rows * avg_io_cost() * engine_block_size/IO_SIZE + +rows * INDEX_BLOCK_COPY_COST + +rows * (ROW_COPY_COST + ROW_LOOKUP_COST) += (When rows are in memory) +rows * INDEX_BLOCK_COPY_COST + +rows * (ROW_COPY_COST + ROW_LOOKUP_COST) + +This gives us: +227.304597596000000 = 1000000 * 3.56e-05 + 1000000*(0.000060865547560 + ROW_LOOKUP_COST) +-> +ROW_LOOKUP_COST= (227.304597596000000 - 1000000 * 3.56e-05 - 1000000*0.000060865547560) / 1000000 = 0.0001308390500 + + +Aria, EQ_REF with index_read +============================ + +select straight_join count(*) from seq_1_to_1000000,test.check_costs_aria where seq=l_linenumber +eq_ref_index_join 499.631749 ms + +According to analyze statement: + +- Cost for SELECT * from seq_1_to_1000000: 12.57 + (From Last_query_cost after the above costs has been applied) +- Time from check_costs: eq_ref's: 499.631749- 12.57s = 487.061749 + +cost= rows * (keyread_time(1,1) + KEY_COPY_COST) + +keyread_time(1,1)= INDEX_BLOCK_COPY_COST + KEY_LOOKUP_COST; + +cost= rows * (KEY_COPY_COST + INDEX_BLOCK_COPY_COST + KEY_LOOKUP_COST) +-> +KEY_LOOKUP_COST= cost/rows - 0.000015685222496 - 0.000035600 +KEY_LOOKUP_COST= 487.061749 / 1000000 - 0.000035600 - 0.000015685222496 +KEY_LOOKUP_COST= 0.000435776526504 + + +MyISAM, TABLE SCAN +================== + +select sum(l_partkey) from test.check_costs_myisam +table_scan ms: 126.353364 + +check_costs.MYD: 109199788 = 26660 IO_SIZE blocks +The row format for MyISAM is similar to Aria, so we use the same +ROW_COPY_COST for Aria. + +cost= blocks * avg_io_cost() * + optimizer_cache_cost * SCAN_LOOKUP_COST + + engine_blocks * INDEX_BLOCK_COPY_COST + + TABLE_SCAN_SETUP_COST + + rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST)); + +MyISAM is using the file system as a row cache. +Let's put the cost of accessing the row in ROW_NEXT_FIND_COST. +Everything is cached (by the file system) and optimizer_cache_cost= 0; + +cost= engine_blocks * INDEX_BLOCK_COPY_COST + + TABLE_SCAN_SETUP_COST + + rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST)) + +ROW_NEXT_FIND_COST= +(costs - engine_blocks * INDEX_BLOCK_COPY_COST - TABLE_SCAN_SETUP_COST)/rows - +ROW_COPY_COST += +(126.353364 - 26660 * 3.56e-05 - 1)/1000000 - 0.000060865547560 +ROW_NEXT_FIND_COST= 0.00006353872044 + + +MyISAM INDEX SCAN +================= + +select count(*) from test.check_costs_myisam force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0; +index_scan ms: 106.490584 + +blocks= index_size/IO_SIZE = +(rows * tot_key_length / INDEX_BLOCK_FILL_FACTOR) / IO_SIZE +-> +1000000 * 19 / 0.75/ 4096 = 6184 +As MyISAM has a block size of 4096 for this table, engine_blocks= 6184 + +cost= keyread_time= blocks * avg_io_cost() * cache + engine_blocks * INDEX_BLOCK_COPY_COST + rows * (KEY_NEXT_FIND_COST + KEY_COPY_COST); +-> +cost= engine_blocks * INDEX_BLOCK_COPY_COST + rows * KEY_NEXT_FIND_COST + +Assuming INDEX_BLOCK_COPY_COST is same as in Aria and the code for +key_copy is identical to Aria: +cost= 6184 * 3.56e-05 + 1000000 * (KEY_NEXT_FIND_COST + KEY_COPY_COST) +-> +KEY_NEXT_FIND_COST= (106.490584 - 6184 * 3.56e-05)/1000000 - 0.000015685222496= +0.000090585211104 + + +MyISAM, RANGE SCAN (scan index, fetch a row for each index entry) +================================================================= + +select sum(l_orderkey) from test.check_costs_myisam force index(l_suppkey) where l_suppkey >= 0 and l_partkey >=0 and l_discount>=0.0 +time: 1202.0894 ms + +cost= keyread_time + rnd_pos_time. +keyread_time is as above in MyISAM INDEX SCAN, but without KEY_COPY_COST: +keyread_time= 106.490584 - KEY_COPY_COST * 1000000= +106.490584 - 0.000015685222496 * 1000000= 90.805361504000000; +rnd_pos_time= 1202.0894 - 90.805361504000000 = 1111.284038496000000 + +rnd_pos_time() = io_cost + engine_mem_cost + + rows * (ROW_LOOKUP_COST + ROW_COPY_COST) = +rows * avg_io_cost() * engine_block_size/IO_SIZE + +rows * INDEX_BLOCK_COPY_COST + +rows * (ROW_COPY_COST + ROW_LOOKUP_COST) += (When rows are in memory) +rows * INDEX_BLOCK_COPY_COST + +rows * (ROW_COPY_COST + ROW_LOOKUP_COST) + +This gives us: + 1111.284038496000000 = 1000000 * 3.56e-05 + 1000000*(0.000060865547560 + ROW_LOOKUP_COST) +-> +ROW_LOOKUP_COST= ( 1111.284038496000000 - 1000000 * (3.56e-05 + 0.000060865547560)) / 1000000s +-> +ROW_LOOKUP_COST= 0.001014818490936 + +As the row is never cached, we have to ensure that rnd_pos_time() +doesn't include an io cost (which would be affected by +optimizer_cache_hit_ratio). This is done by having a special +ha_myisam::rnd_pos_time() that doesn't include io cost but instead an +extra cpu cost. + + +MyISAM, EQ_REF with index_read +============================== + +select straight_join count(*) from seq_1_to_1000000,test.check_costs_myisam where seq=l_linenumber; +eq_ref_join ms: 613.906777 of which 12.48 ms is for seq_1_to_1000000; + +According to analyze statement: + +- Cost for SELECT * from seq_1_to_1000000: 12.48 (See sequence_scan_cost) +- Time from check_costs: eq_ref's: 613.906777- 12.48 = 601.426777; + +cost= rows * (keyread_time(1) + KEY_COPY_COST) + +keyread_time(1)= INDEX_BLOCK_COPY_COST + KEY_LOOKUP_COST; + +cost= rows * (KEY_COPY_COST + INDEX_BLOCK_COPY_COST + KEY_LOOKUP_COST) +-> +KEY_LOOKUP_COST= cost/rows - INDEX_BLOCK_COPY_COST - KEY_COPY_COST; +601.426777 / 1000000 - 3.56e-05 - 0.000015685222496 = 0.00055014155451 +KEY_LOOKUP_COST= 0.00055014155451 + + + +InnoDB, TABLE SCAN +================== + +select sum(l_quantity) from check_costs_innodb; +table_scan 131.302492 +Note that InnoDB reported only 956356 rows instead of 100000 in stats.records +This will will cause the optimizer to calculate the costs based on wrong +assumptions. + +As InnoDB have a clustered index (which cost is a combination of +KEY_LOOKUP_COST + ROW_COPY_COST), we have to ensure that the +relationship between KEY_COPY_COST and ROW_COPY_COST is close to the +real time of copying a key and a row. + +I assume, for now, that the row format for InnoDB is not that +different than for Aria (in other words, computation to unpack is +about the same), so lets use the same ROW_COPY_COST (0.000060865547560) + +I am ignoring the fact that InnoDB can optimize row copying by only +copying the used fields as the optimizer currently have to take that +into account. (This would require a way to update ROW_COPY_COST / +table instance in the query). + +For now, lets also use the same value as Aria for +INDEX_BLOCK_COPY_COST (3.56e-05). + +The number of IO_SIZE blocks in the InnoDB data file is 34728 (from gdb)) +(For reference, MyISAM was using 26660 and Aria 30002 blocks) +As InnoDB is using 16K blocks, the number of engine blocks= 34728/4= 8682 + +cost= blocks * avg_io_cost() * + optimizer_cache_cost * SCAN_LOOKUP_COST + + engine_blocks * INDEX_BLOCK_COPY_COST + + TABLE_SCAN_SETUP_COST + + rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST)); + +as optimizer_cache_cost = 0 + +cost= engine_blocks * INDEX_BLOCK_COPY_COST + + TABLE_SCAN_SETUP_COST + + rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST)) + +ROW_NEXT_FIND_COST= +(costs - engine_blocks * INDEX_BLOCK_COPY_COST - TABLE_SCAN_SETUP_COST)/rows - +ROW_COPY_COST += (Ignoring TABLE_SCAN_SETUP_COST, which is just 10 usec) +(131.302492 - 8682 * 3.56e-05)/1000000 - 0.000060865547560 = +0.00007012786523999997 + + +InnoDB INDEX SCAN +================= + +select count(*) from check_costs_innodb force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0; +index_scan 114.733037 ms +Note that InnoDB is reporting 988768 rows instead of 1000000 +(The number varies a bit between runs. At another run I got 956356 rows) +With default costs (as of above), we get a query cost of 112.142. This can +still be improved a bit... + +blocks= index_size/IO_SIZE = +(rows * tot_key_length / INDEX_BLOCK_FILL_FACTOR) / IO_SIZE +-> (total_key_length is 17 in InnoDB, 19 in Aria) +1000000 * 17 / 0.75/ 4096 = 5533 +engine_blocks= 5533/4 = 1383 + +(In reality we get 5293 blocks and 1323 engine blocks, because of the +difference in InnoDB row count) + +cost= keyread_time= blocks * avg_io_cost() * cache + engine_blocks * INDEX_BLOCK_COPY_COST + rows * (KEY_NEXT_FIND_COST + KEY_COPY_COST); +-> +cost= engine_blocks * INDEX_BLOCK_COPY_COST + rows * KEY_NEXT_FIND_COST + +Assuming INDEX_BLOCK_COPY_COST is same as in Aria: +(Should probably be a bit higher as block_size in InnoDB is 16384 +compared to 8192 in Aria) + +cost= 1383 * 3.56e-05 + 1000000 * (KEY_NEXT_FIND_COST + KEY_COPY_COST) += +KEY_NEXT_FIND_COST + KEY_COPY_COST= (114.733037 - 1383 * 3.56e-05)/1000000 += +KEY_NEXT_FIND_COST= (114.733037 - 1383 * 3.56e-05)/1000000 - 0.000015685222496 +-> +KEY_NEXT_FIND_COST=0.000098998579704; + +Setting this makes InnoDB calculate the cost to 113.077711 (With estimate of +988768 rows) +If we would have the right number of rows in ha_key_scan_time, we would +have got a cost of: + +Last_query_cost: 145.077711 (Including WHERE cost for 988768 row) +(145.077711)/988768*1000000.0-32 = 114.72573444933 + + +InnoDB RANGE SCAN +================= + +select sum(l_orderkey) from check_costs_innodb force index(l_suppkey) where l_suppkey >= 0 and l_partkey >=0 and l_discount>=0.0 +range_scan 961.4857045 ms +Note that InnoDB was reporting 495340 rows instead of 1000000 ! +I added a patch to fix this and now InnoDB reports 990144 rows + +cost= keyread_time + rnd_pos_time. +keyread_time is as above in index scan, but we want it without KEY_COPY_COST: +keyread_time= cost - KEY_COPY_COST * 1000000= +114.733037 - 0.000015685222496 * 1000000= 99.047814504000000 +rnd_pos_time= 961.4857045 - 99.047814504000000 = 862.437889996000000 + +rnd_pos_time() = io_cost + engine_mem_cost + + rows * (ROW_LOOKUP_COST + ROW_COPY_COST) = +rows * avg_io_cost() * engine_block_size/IO_SIZE + +rows * INDEX_BLOCK_COPY_COST + +rows * (ROW_COPY_COST + ROW_LOOKUP_COST) += (When rows are in memory) + +rows * (INDEX_BLOCK_COPY_COST + ROW_COPY_COST + ROW_LOOKUP_COST) + +This gives us: +862.437889996000000 = 1000000 * 3.56e-05 + 1000000*(0.000060865547560 + ROW_LOOKUP_COST) +-> +ROW_LOOKUP_COST= (862.437889996000000 - 1000000*(3.56e-05+0.000060865547560)) / 1000000 +-> +ROW_LOOKUP_COST= 0.000765972342436 + +Setting this makes InnoDB calculate the cost to 961.081050 (good enough) + + +InnodDB EQ_REF with index_read +============================== + +select straight_join count(*) from seq_1_to_1000000,test.check_costs_innodb where seq=l_linenumber +time: 854.980610 ms + +Here the engine first has to do a key lookup and copy the key to the upper +level (Index only read). + +According to analyze statement: + +- Cost for SELECT * from seq_1_to_1000000: 12.57 (See sequence_scan_cost) +- Time from check_costs: eq_ref_join: 854.980610 + This is time for accessing both seq_1_to_1000000 and check_costs + time for check_cost_innodb: 854.980610-12.57 = 842.410610 ms + +cost= rows * (keyread_time(1,1) + KEY_COPY_COST) + +keyread_time(1,1)= INDEX_BLOCK_COPY_COST + ranges * KEY_LOOKUP_COST + + (rows-ranges) * KEY_NEXT_FIND_COST + +As rows=1 and ranges=1: + +keyread_time(1,1)= INDEX_BLOCK_COPY_COST + KEY_LOOKUP_COST + +cost= rows * (KEY_COPY_COST + INDEX_BLOCK_COPY_COST + KEY_LOOKUP_COST) +-> +KEY_LOOKUP_COST= cost/rows - INDEX_BLOCK_COPY_COST - KEY_COPY_COST; +842.410610 / 1000000 - 3.56e-05 - 0.000015685222496 +-> +KEY_LOOKUP_COST= 0.000791125387504; + +After the above we have +last_query_cost=918.986438; + +The cost for check_costs_innodb = +last_query_cost - sequence_scan_cost - where_cost*2 = +918.986438 - 12.57 - 32*2 = 842.416438 (ok) + + +InnodDB EQ_REF with clustered index read +======================================== + +select straight_join count(*) from seq_1_to_1000000,check_costs_innodb where seq=l_orderkey +eq_ref_cluster_join time: 972.290773 ms + +According to analyze statement: +- Cost for SELECT * from seq_1_to_1000000: 12.57 (See sequence_scan_cost) +- Time from check_costs: eq_ref_cluster_join: 972.290773 ms + This is time for accessing both seq_1_to_1000000 and check_costs_innodb. + Time for check_cost_innodb: 972.290773 - 12.57 = 959.790773 + +The estimated cost is 875.0160 + +cost= rows * (keyread_time(1,1) + + ranges * ROW_LOOKUP_COST + + (rows - ranges) * ROW_NEXT_FIND_COST + + rows * ROW_COPY_COST) + +As rows=1 and ranges=1: + +cost= rows * (INDEX_BLOCK_COPY_COST + ROW_LOOKUP_COST + ROW_COPY_COST); +-> +ROW_LOOKUP_COST= cost/rows - INDEX_BLOCK_COPY_COST - ROW_COPY_COST; +959.790773 / 1000000 - 3.56e-05 - 0.000060865547560 +-> +ROW_LOOKUP_COST= 0.0008633252254400001 + +From InnoDB RANGE SCAN we have ROW_LOOKUP_COST=0.000765972342436 +From EQ_REF with index read we have KEY_LOOKUP_COST= 0.000791125387504, +which should in theory be identical to ROW_LOOKUP_COST, + +For now we have to live with the difference (as I want to have the project done +for the next release). + +The difference could be come from the following things: + +- InnoDB estimation of rows in the range scan test is a bit off. +- Maybe the work to find a row from an internal key entry compared to + a external key is a bit difference (less checking/conversions) +- There is different keys used for range scan and this test that could have + different costs +- Maybe we should increase ROW_COPY_COST or ROW_LOOKUP_COST for InnoDB + and adjust other costs. + + +Some background. In range scan, the cost is: +- Scanning over all keys + - For each key, fetch row using rowid + +For the EQ_REF cache +- Scan seq_1_to_1000000 + for each value in seq + do a index_read() call + + +Archive scan cost +================= + +table_scan time: 757.390280 ms +rows: 1000000 +file size: 32260650 = 7878 IO_SIZE blocks + +cost= scan_time() + TABLE_SCAN_SETUP_COST + + records * (ROW_COPY_COST + ROW_LOOKUP_COST + WHERE_COMPARE_COST); + +757.390280 = scan_time() + 10 + 1000000 * (0.060866+0.032000) +-> +scan_time()= 757.390280 - (10 + 1000000 * (0.060866+0.032000)/1000) = 654.52428 + +scan_time() is defined as: + +cost.cpu= (blocks * DISK_READ_COST * DISK_READ_RATIO + + blocks * ARCHIVE_DECOMPRESS_TIME); + +Default values for above: +blocks= 7878 +DISK_READ_COST: 10.240000 usec +DIUSK_READ_RATIO= 0.20 +-> +ARCHIVE_COMPRESS_TIME= (654.52428 - (7878 * 10.240000/1000*0.2)) / 7878 = +0.081034543792841 + + +MyRocksDB, TABLE SCAN +===================== + +select sum(l_quantity) from check_costs_rocksdb; +table_scan 213.038648 ms + +cost= blocks * avg_io_cost() * + optimizer_cache_cost * SCAN_LOOKUP_COST + + engine_blocks * INDEX_BLOCK_COPY_COST + + TABLE_SCAN_SETUP_COST + + rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST)); + +Some defaults: +optimizer_cache_cost = 0 +index_block_copy_cost= 0.000035600 (Assume same as innoDB) +table_scan_setup_cost= 0 (Lets ignore it for now) +row_copy_cost=0.000060865547560 (Assume same as InnoDB for now) + +show table status tells us that datalength=64699000 = 15795 4K-blocks. + +cost= engine_blocks * INDEX_BLOCK_COPY_COST + + TABLE_SCAN_SETUP_COST + + rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST)) + +ROW_NEXT_FIND_COST= +(costs - engine_blocks * INDEX_BLOCK_COPY_COST)/rows - +ROW_COPY_COST += (213.03868 - 15796 * 0.000035600 - 0)/1000000 - 0.000060865547560 = +0.00015161079484 + + +MyRocks INDEX SCAN +================== + +select count(*) from test.check_costs_rocksdb force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0 +index_scan 266.80435 ms + +Note that myrocks returns 2M rows for the table when it has only 1M rows! + +block_size= 8192 +key_length= 18 +compression=0.25 (75 %) +blocks= (key_length * rows) / 4 * block_size/4096 = 18 * 1000000/4 * 2= +2198 IO_BLOCKS (=1094 engine_blocks) + +cost= keyread_time= blocks * avg_io_cost * DISK_READ_RATIO + engine_blocks * INDEX_BLOCK_COPY_COST + rows * (KEY_NEXT_FIND_COST + KEY_COPY_COST); + +As we assume that everything is in memory (DISK_READ_RATIO=0) +-> +cost= engine_blocks * INDEX_BLOCK_COPY_COST + rows * KEY_NEXT_FIND_COST; + +Assuming INDEX_BLOCK_COPY_COST and KEY_COPY_COST are same as in Aria and InnoDB) + +cost= 1094 * 3.56e-05 + 1000000 * (KEY_NEXT_FIND_COST + KEY_COPY_COST) += +KEY_NEXT_FIND_COST + KEY_COPY_COST= (266.80435 - 1094 * 3.56e-05)/1000000 += +KEY_NEXT_FIND_COST= (266.80435 - 1094 * 3.56e-05)/1000000 - 0.000015685222496 +-> +KEY_NEXT_FIND_COST= 0.000251080181104 + + +MyRocks EQ_REF with index_read +============================== + +select straight_join count(*) from seq_1_to_1000000,test.check_costs_rocksdb where seq=l_linenumber +time: 857.548991 + +Here the engine first has to do a key lookup and copy the key to the upper +level (Index only read). + +According to analyze statement: + +- Cost for SELECT * from seq_1_to_1000000: 12.57 (See sequence_scan_cost) +- Time from check_costs: eq_ref_join: 857.548991 + This is time for accessing both seq_1_to_1000000 and check_costs + time for check_cost_innodb: 857.548991-12.57 = 844.978991 ms + +cost= rows * (keyread_time(1,1) + KEY_COPY_COST) + +keyread_time(1,1)= INDEX_BLOCK_COPY_COST + ranges * KEY_LOOKUP_COST + + (rows-ranges) * KEY_NEXT_FIND_COST + +As rows=1 and ranges=1: + +keyread_time(1,1)= INDEX_BLOCK_COPY_COST + KEY_LOOKUP_COST + +cost= rows * (KEY_COPY_COST + INDEX_BLOCK_COPY_COST + KEY_LOOKUP_COST) +-> +KEY_LOOKUP_COST= cost/rows - INDEX_BLOCK_COPY_COST - KEY_COPY_COST; +844.978991 / 1000000 - 3.56e-05 - 0.000015685222496 = 0.000793693768504 + + +MyRocks EQ_REF with clustered index read +======================================== + +select straight_join count(*) from seq_1_to_1000000,check_costs_rocksdb where seq=l_orderkey +eq_ref_cluster_join 1613.5670 ms + +According to analyze statement: +- Cost for SELECT * from seq_1_to_1000000: 12.57 (See sequence_scan_cost) +- Time from check_costs: eq_ref_cluster_join: 1613.5670 ms + This is time for accessing both seq_1_to_1000000 and check_costs_innodb. + Time for check_cost_rocksdb: 1613.5670 - 12.57 = 1600.9970 + +cost= rows * (keyread_time(1,1) + + ranges * ROW_LOOKUP_COST + + (rows - ranges) * ROW_NEXT_FIND_COST + + rows * ROW_COPY_COST) + +As rows=1 and ranges=1: + +cost= rows * (INDEX_BLOCK_COPY_COST + ROW_LOOKUP_COST + ROW_COPY_COST); +-> +ROW_LOOKUP_COST= cost/rows - INDEX_BLOCK_COPY_COST - ROW_COPY_COST; +1600.9970 / 1000000 - 3.56e-05 - 0.000060865547560 = 0.00150453145244 + + +MyRocks Range scan +================== +select sum(l_orderkey) from test.check_costs_rocksdb force index(l_suppkey) where l_suppkey >= 0 and l_partkey >=0 and l_discount>=0.0 + +The MyRocks engine estimates the number of rows both for the table and +for the to be about 2M, double the real ammount. + +The timing and costs from check_costs.pl are: + +range_scan time: 1845.06126 ms cost-where: 3698.8919 cost: 3730.8919 + +As the costs are about the double of the time, this is as good as we can do things until +MyRocks reported record count is corrected + +The issue with wrongly estimated number of rows does not affect the other results from check_costs.pl +as table scans estimates uses the number of rows from the analyze, not from the engine. + + +Appendix +======== + +Future improvements +=================== + +The current costs are quite good for tables of 1M rows (usually about +10% from the true cost for the test table). + +For smaller tables the costs will be a bit on the high side and for +bigger tables a bit on the low size for eq_ref joins (both with index +and with row lookup). + +The only engine that takes into account the number of rows for key lookups +is heap with binary-tree indexes. + +Ideas of how to fix this: + +- Change KEY_LOOKUP_COST, INDEX_BLOCK_COPY_COST and ROW_LOOKUP_COST + (for clustered index) to take into account the hight of the B tree. + + +Observations +============ + +Ratio between table scan and range scan + +Quereyies used: +select sum(l_quantity) from check_costs_aria; +select sum(l_orderkey) from test.check_costs_aria force index(l_suppkey) where l_suppkey >= 0 and l_partkey >=0 and l_discount>=0.0; + +The test for Aria shows that cost ratio of range_scan/table_scan are: +disk_read_ratio=0 341.745207/139.348286= 2.4524536097 +disk_read_ratio=0.02 752.408528/145.748695= 5.1623688843 +disk_read_ratio=0.20 4448.378423/203.352382= 21.8752216190 + +As we are using disk_read_ratio=0.02 by default, this means that in +mtr to not use table scan instead of range, we have to ensure that the +range does not cover more than 1/5 of the total rows. + + +Trying to understand KEY_COPY_COST +================================== + +An index scan with 2 and 4 key parts on an Aria table. +The index has null key parts, so packed keys are used. + +Query1 "index_scan" (2 integer key parts, both key parts may have NULLS): +select count(*) from $table force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0"); + +- Optimized build: Average 164 ms/query +- gprof build: Average 465 ms/query + +[16] 51.2 0.00 0.21 3999987 handler::ha_index_next() +[15] 51.2 0.01 0.20 3999993 maria_rnext [15] +[22] 19.5 0.08 0.00 9658527 _ma_get_pack_key [22] + +This means that for 3999987 read next calls, the time of _ma_get_pack_key +to retrieve the returned key is: +0.08 * (3999987/9658527) + +The relation of KEY_COPY_COST to KEY_NEXT_FIND_COST is thus for Aria: + +0.08 * (3999987/9658527)/0.21 = 0.15777 parts of KEY_NEXT_FIND_COST + +------ + +Query 2 "index_scan_4_parts" (4 integer key parts, 2 parts may have NULL's): +select count(*) from $table force index (long_suppkey) where l_linenumber >= 0 and l_extra >0"); + +- Optimized build: 218 ms +- gprof build: Average 497 ms/query + +Most costly functions + % cumulative self self total + time seconds seconds calls ms/call ms/call name + 13.44 0.61 0.61 48292742 0.00 0.00 _ma_get_pack_key + 8.59 1.00 0.39 28298101 0.00 0.00 ha_key_cmp + 7.27 1.33 0.33 19999951 0.00 0.00 _ma_put_key_in_record + 4.41 1.96 0.20 19999952 0.00 0.00 handler::ha_index_next(unsigned char*) + +Call graph +[13] 9.0 0.20 0.21 19999952 handler::ha_index_next(unsigned char*) [13] + +[3] 21.6 0.16 0.82 19999960 _ma_search_next [3] +[18] 7.7 0.02 0.33 19999951 _ma_read_key_record [18] + 0.00 0.00 19887291/19999952 _ma_get_static_key [6565][19] + 18.4 0.10 0.64 19999936 Item_cond_and::val_int() [19] + +-> KEY_COPY_COST = 1.33/1.96 = 0.6785 parts of the index_read_next + +Total cost increase from 2 -> 4 key parts = 1.96 / 1.40 = 40% +This includes the additional work in having more key pages, more work in +finding next key (if key parts are packed or possible null) ,and copying +the key parts to the record + +I also did a quick analyze between using NOT NULL keys, in which case +Aria can use fixed key lengths. This gives a 39.4% speed up on index +scan, a small speedup to table scan (as 2 fields are cannot have null) +but not a notable speed up for anything else. + + +Trying to understand ROW_COPY_COST +================================== + +An simple table scan on an Aria table + +query: select sum(l_quantity) from check_costs_aria + +From gprof running the above query 10 times with 1M rows in the table: + +[14] 83.7 0.03 0.76 9999989 handler::ha_rnd_next() +[17] 51.6 0.49 0.00 10000010 _ma_read_block_record2 [17] +[18] 21.1 0.01 0.19 156359 pagecache_read [18] + +The function that unpacks the row is _ma_read_block_record2() + +Taking into account that all pages are cached: +(Note that the main cost in pagecache_read in this test is calculating the page +checksum) + +ROW_COPY_COST/ROW_NEXT_FIND_COST= 0.49/(0.76+0.3-0.20) = 0.56977 = 0.57 + + +Reason for SCAN_SETUP_COSTS +=========================== + +One problem with the new more exact cost model is that the optimizer +starts to use table scans much more for small tables (which is correct when +one looks at cost). However, small tables are usually cached fully so +it is still better to use index scan in many cases. + +This problem is especially notable in mtr where most test cases uses +tables with very few rows. + +TABLE_SCAN_SETUP_COST is used to add a constant startup cost for +table and index scans. It is by default set to 10 usec, about 10 MyISAM +row reads. + +The following cost calculation shows why this is needed: + +explain select count(*) from t1, t2 where t1.p = t2.i ++------+-------------+-------+-------+---------------+---------+---------+-----------+------+-------------+ +| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | ++------+-------------+-------+-------+---------------+---------+---------+-----------+------+-------------+ +| 1 | SIMPLE | t1 | index | PRIMARY | PRIMARY | 4 | NULL | 2 | Using index | +| 1 | SIMPLE | t2 | ref | k1 | k1 | 5 | test.t1.p | 2 | Using index | ++------+-------------+-------+-------+---------------+---------+---------+-----------+------+-------------+ + +t1 has 2 rows +t2 has 4 rows + +Optimizer trace shows when using TABLE_SCAN_SETUP_COST=0: + +index scan costs +"read_cost": 0.00308962, +read_and_compare_cost": 0.00321762 + +key read costs: +"rows": 2, +"cost": 0.00567934 + +CHOSEN: +Scan with join cache: cost": 0.0038774 +rows_after_scan": 2 + +Note that in the following, we are using cost in microseconds while +the above costs are in milliseconds. + +select * from information_schema.optimizer_costs where engine="myisam"\G + ENGINE: MyISAM + OPTIMIZER_DISK_READ_COST: 10.240000 + OPTIMIZER_INDEX_BLOCK_COPY_COST: 0.035600 + OPTIMIZER_KEY_COMPARE_COST: 0.008000 + OPTIMIZER_KEY_COPY_COST: 0.066660 + OPTIMIZER_KEY_LOOKUP_COST: 0.498540 + OPTIMIZER_KEY_NEXT_FIND_COST: 0.060210 + OPTIMIZER_DISK_READ_RATIO: 0.200000 +OPTIMIZER_RND_POS_INTERFACE_COST: 0.000000 + OPTIMIZER_ROW_COPY_COST: 0.088630 + OPTIMIZER_ROW_LOOKUP_COST: 0.641150 + OPTIMIZER_ROW_NEXT_FIND_COST: 0.049510 + OPTIMIZER_ROWID_COMPARE_COST: 0.004000 +@@OPTIMIZER_SCAN_SETUP_COST 10.000000 +@@OPTIMIZER_WHERE_COST 0.032000 + +Checking the calculated costs: + +index_scan_cost= 10.240000 * 0.2 + 0.035600 + 0.498540 + 4 * (0.060210+0.066660) = 3.08962 +where_cost 0.032000*4= 0.128000 +total: 3.21762 + +key_read_cost= 10.240000 * 0.2 + 0.035600 + 0.498540 + 0.060210 = 2.64235 +key_copy_cost= 0.066660 * 2 = 0.13332 +where_cost 0.032000*2= 0.06400 +total: 2.64235 + 0.13332 + 0.06400 = 2.8396699999999999 +Needs to be done 2 times (2 rows in t1): 5.67934 + +Join cache only needs 1 refill. The calculation is done in +sql_select.cc:best_access_path() + +scan_with_join_cache= +scan_time + cached_combinations * ROW_COPY_COST * JOIN_CACHE_COST + +row_combinations * (ROW_COPY_COST * JOIN_CACHE_COST + WHERE_COST) = +3.2176 + 2 * 0.088630 + 2*2 * (0.088630 * 1 + 0.032000) = +3.87738 + +Other observations: +OPTIMIZER_KEY_NEXT_FIND_COST + OPTIMIZER_KEY_COPY_COST + OPTIMIZER_WHERE_COST= +0.060210 + 0.066660 + 0.032000 = 0.158870 +OPTIMIZER_KEY_LOOKUP_COST / 0.158870 = 3.138 + +This means that when using index only reads (and DISK_READ_RATIO=0) +the optimizer will prefer to use 3 times more keys in range or ref +than doing a key lookups! +If DISK_READ_RATIO is higher, the above ratio increases. This is one of +the reasons why we set the default value for DISK_READ_RATIO quite low +(0.02 now) + +(OPTIMIZER_ROW_COPY_COST + OPTIMIZER_ROW_NEXT_FIND_COST) / +(OPTIMIZER_KEY_COPY_COST + OPTIMIZER_KEY_NEXT_FIND_COST) = +(0.088630 + 0.049510) / (0.066660 + 0.060210) = 1.08831 +Which means that table scans and index scans have almost the same cost. +select 0.066660 + + +HEAP_TEMPTABLE_CREATE_COST +========================== + +I added trackers in create_tmp_table() and open_tmp_table() and run a +simple query that create two materialized temporary table with an unique +index 31 times. I got the following tracking information: + +(gdb) p open_tracker +$1 = {counter = 31, cycles = 302422} +(gdb) p create_tracker +$2 = {counter = 31, cycles = 1479836} + +Cycles per create = (302422 + 1479836)/31= 57492 + +1000.0*57492/sys_timer_info.cycles.frequency = 0.0249 ms +HEAP_TMPTABLE_CREATE_COST= 0.025 ms + + +What to do with wrong row estimates +=================================== + +MyRocks can have a very bad estimate of rows, both for the number of rows in the table and also +for big ranges. Analyze table can fix this, but we have to consider how to keep the row estimate +correct when tables are growing over time. + +Suggested fixed: +- If we can assume that the datafile size reported by the engine is somewhat correct, we could + estimate the number of rows as: + analyze_number_of_rows * current_datafile_size / analyze_datafile_size + + +MySQL cost structures +===================== + +MySQL 8.0 server cost are stored in the class Server_cost_constants defined +int opt_costconstants.h + +It containts the following slots and has the following default values: + +m_row_evaluate_cost 0.1 Cost for evaluating the query condition on + a row +m_key_compare_cost 0.05 Cost for comparing two keys +m_memory_temptable_create_cost 1.0 Cost for creating an internal temporary + table in memory +m_memory_temptable_row_cost 0.1 Cost for retrieving or storing a row in an + internal temporary table stored in memory. +m_disk_temptable_create_cost 20.0 Cost for creating an internal temporary + table in a disk resident storage engine. +m_disk_temptable_row_cost 0.5 Cost for retrieving or storing a row in an + internal disk resident temporary table. + +Engine cost variables: +m_memory_block_read_cost 0.25 The cost of reading a block from a main + memory buffer pool +m_io_block_read_cost 1.0 The cost of reading a block from an + IO device (disk) + +------- + +Some cost functions: + +scan_time() = data_file_length / IO_SIZE + 2; +read_time(index, ranges, rows)= rows2double(ranges + rows); +index_only_read_time()= records / keys_per_block + +table_scan_cost()= scan_time() * page_read_cost(1.0); + +index_scan_cost()= index_only_read_time(index, rows) * + page_read_cost_index(index, 1.0); +read_cost()= read_time() * page_read_cost(1.0); + + +page_read_cost()= buffer_block_read_cost(pages_in_mem) + + io_block_read_cost(pages_on_disk); + +io_block_read_cost()= blocks * m_io_block_read_cost +buffer_block_read_cost()= blocks * m_memory_block_read_cost; + + +There are also: +table_in_memory_estimate() +index_in_memory_estimate() + +If the storage engine is not providing estimates for the above, then +the estimates are done based on table size (not depending on how many +rows are going to be accessed in the table). diff --git a/VERSION b/VERSION index 2b0eac3dbce..c1aee6d461c 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=11 MYSQL_VERSION_MINOR=0 MYSQL_VERSION_PATCH=1 -SERVER_MATURITY=gamma +SERVER_MATURITY=alpha diff --git a/client/mysql.cc b/client/mysql.cc index 363677785d5..9971410c0d8 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -46,7 +46,7 @@ #include #endif -const char *VER= "15.1"; +const char *VER= "15.2"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -246,7 +246,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, - auto_vertical_output= 0, + auto_vertical_output= 0, show_query_cost= 0, show_warnings= 0, executing_query= 0, ignore_spaces= 0, opt_binhex= 0, opt_progress_reports; static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; @@ -324,6 +324,7 @@ static int com_quit(String *str,char*), com_notee(String *str, char*), com_charset(String *str,char*), com_prompt(String *str, char*), com_delimiter(String *str, char*), com_warnings(String *str, char*), com_nowarnings(String *str, char*); +static int com_query_cost(String *str, char*); #ifdef USE_POPEN static int com_nopager(String *str, char*), com_pager(String *str, char*), @@ -395,6 +396,8 @@ static COMMANDS commands[] = { { "print", 'p', com_print, 0, "Print current command." }, { "prompt", 'R', com_prompt, 1, "Change your mysql prompt."}, { "quit", 'q', com_quit, 0, "Quit mysql." }, + { "costs", 'Q', com_query_cost, 0, + "Toggle showing query costs after each query" }, { "rehash", '#', com_rehash, 0, "Rebuild completion hash." }, { "source", '.', com_source, 1, "Execute an SQL script file. Takes a file name as an argument."}, @@ -1156,6 +1159,7 @@ static void print_table_data_xml(MYSQL_RES *result); static void print_tab_data(MYSQL_RES *result); static void print_table_data_vertically(MYSQL_RES *result); static void print_warnings(void); +static void print_last_query_cost(void); static void end_timer(ulonglong start_time, char *buff); static void nice_time(double sec,char *buff,bool part_second); extern "C" sig_handler mysql_end(int sig) __attribute__ ((noreturn)); @@ -1828,6 +1832,10 @@ static struct my_option my_long_options[] = {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.", &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"show-query-costs", OPT_SHOW_WARNINGS, + "Show query cost after every statement.", + &show_query_cost, &show_query_cost, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -3586,6 +3594,8 @@ end: /* Show warnings if any or error occurred */ if (show_warnings == 1 && (warnings >= 1 || error)) print_warnings(); + if (show_query_cost) + print_last_query_cost(); if (!error && !status.batch && (mysql.server_status & SERVER_STATUS_DB_DROPPED)) @@ -4190,6 +4200,33 @@ end: } +/* print_last_query_cost */ + +static void print_last_query_cost() +{ + const char *query; + char *end; + MYSQL_RES *result; + MYSQL_ROW cur; + + query= "show status like 'last_query_cost'"; + mysql_real_query_for_lazy(query, strlen(query)); + mysql_store_result_for_lazy(&result); + if (!result) + goto end; + + cur= mysql_fetch_row(result); + if (strtod(cur[1], &end) != 0.0) + { + init_pager(); + tee_fprintf(PAGER, "%s: %s\n\n", cur[0], cur[1]); + } + +end: + mysql_free_result(result); +} + + static const char *array_value(const char **array, char key) { for (; *array; array+= 2) @@ -4765,6 +4802,18 @@ com_nowarnings(String *buffer __attribute__((unused)), return 0; } +static int +com_query_cost(String *buffer __attribute__((unused)), + char *line __attribute__((unused))) +{ + show_query_cost= 1 - show_query_cost; + if (show_query_cost) + put_info("Last_query_cost enabled.",INFO_INFO); + else + put_info("Last_query_cost disabled.",INFO_INFO); + return 0; +} + /* Gets argument from a command on the command line. If mode is not GET_NEXT, skips the command and returns the first argument. The line is modified by @@ -5020,6 +5069,10 @@ com_status(String *buffer __attribute__((unused)), ulonglong id; MYSQL_RES *UNINIT_VAR(result); + /* + Don't remove "limit 1", + it is protection against SQL_SELECT_LIMIT=0 + */ if (mysql_real_query_for_lazy( C_STRING_WITH_LEN("select DATABASE(), USER() limit 1"))) return 0; @@ -5027,10 +5080,6 @@ com_status(String *buffer __attribute__((unused)), tee_puts("--------------", stdout); usage(1); /* Print version */ tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql)); - /* - Don't remove "limit 1", - it is protection against SQL_SELECT_LIMIT=0 - */ if (!mysql_store_result_for_lazy(&result)) { MYSQL_ROW cur=mysql_fetch_row(result); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 9682f346253..d3e5f96faea 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -8607,6 +8607,7 @@ end: var_set_errno(mysql_stmt_errno(stmt)); + display_optimizer_trace(cn, ds); revert_properties(); /* Close the statement if reconnect, need new prepare */ diff --git a/cmake/configure.pl b/cmake/configure.pl index 4085110b6fa..87099169b85 100644 --- a/cmake/configure.pl +++ b/cmake/configure.pl @@ -190,7 +190,7 @@ foreach my $option (@ARGV) $cmakeargs = $cmakeargs." -DWITH_SSL=system"; next; } - if($option =~ /with-ssl$/) + if($option =~ /with-ssl$/ || $option =~ /with-ssl=bundled/) { $cmakeargs = $cmakeargs." -DWITH_SSL=bundled"; next; diff --git a/include/my_compare.h b/include/my_compare.h index c2cb9ae46b9..62bb6ac0ed4 100644 --- a/include/my_compare.h +++ b/include/my_compare.h @@ -154,6 +154,5 @@ typedef enum check_result { typedef check_result_t (*index_cond_func_t)(void *param); typedef check_result_t (*rowid_filter_func_t)(void *param); -typedef int (*rowid_filter_is_active_func_t)(void *param); #endif /* _my_compare_h */ diff --git a/include/my_getopt.h b/include/my_getopt.h index ffff706e015..26f21bd632e 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -100,7 +100,6 @@ typedef my_bool (*my_get_one_option)(const struct my_option *, const char *, con typedef void *(*my_getopt_value)(const char *, uint, const struct my_option *, int *); - extern char *disabled_my_option; extern char *autoset_my_option; extern my_bool my_getopt_print_errors; diff --git a/include/my_global.h b/include/my_global.h index 38bee0163ad..730139be5f2 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -682,6 +682,7 @@ typedef SOCKET_SIZE_TYPE size_socket; Io buffer size; Must be a power of 2 and a multiple of 512. May be smaller what the disk page size. This influences the speed of the isam btree library. eg to big to slow. + 4096 is a common block size on SSDs. */ #define IO_SIZE 4096U /* diff --git a/include/my_sys.h b/include/my_sys.h index 699f13bfcf1..f52510d629e 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -353,6 +353,14 @@ typedef struct st_dynamic_array myf malloc_flags; } DYNAMIC_ARRAY; + +typedef struct st_dynamic_array_append +{ + DYNAMIC_ARRAY *array; + uchar *pos, *end; +} DYNAMIC_ARRAY_APPEND; + + typedef struct st_my_tmpdir { DYNAMIC_ARRAY full_list; @@ -782,7 +790,7 @@ extern int flush_write_cache(RECORD_CACHE *info); extern void handle_recived_signals(void); extern sig_handler my_set_alarm_variable(int signo); -extern my_bool radixsort_is_appliccable(uint n_items, size_t size_of_element); +extern my_bool radixsort_is_applicable(uint n_items, size_t size_of_element); extern void my_string_ptr_sort(uchar *base,uint items,size_t size); extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements, size_t size_of_element,uchar *buffer[]); @@ -856,6 +864,10 @@ extern void freeze_size(DYNAMIC_ARRAY *array); #define push_dynamic(A,B) insert_dynamic((A),(B)) #define reset_dynamic(array) ((array)->elements= 0) #define sort_dynamic(A,cmp) my_qsort((A)->buffer, (A)->elements, (A)->size_of_element, (cmp)) +extern void init_append_dynamic(DYNAMIC_ARRAY_APPEND *append, + DYNAMIC_ARRAY *array); +extern my_bool append_dynamic(DYNAMIC_ARRAY_APPEND *append, + const void * element); extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str, size_t init_alloc,size_t alloc_increment); diff --git a/include/my_tracker.h b/include/my_tracker.h new file mode 100644 index 00000000000..88cefe5ef5d --- /dev/null +++ b/include/my_tracker.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2022, MariaDB Corporation. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +/* + Trivial framework to add a tracker to a C function +*/ + +#include "my_rdtsc.h" + +struct my_time_tracker +{ + ulonglong counter; + ulonglong cycles; +}; + +#ifdef HAVE_TIME_TRACKING +#define START_TRACKING ulonglong my_start_time= my_timer_cycles() +#define END_TRACKING(var) \ + { \ + ulonglong my_end_time= my_timer_cycles(); \ + (var)->counter++; \ + (var)->cycles+= (unlikely(my_end_time < my_start_time) ? \ + my_end_time - my_start_time + ULONGLONG_MAX : \ + my_end_time - my_start_time); \ + } +#else +#define START_TRACKING +#define END_TRACKING(var) do { } while(0) +#endif diff --git a/include/myisam.h b/include/myisam.h index c90026bfc7a..dd4f9084b00 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -435,6 +435,8 @@ int thr_write_keys(MI_SORT_PARAM *sort_param); int sort_write_record(MI_SORT_PARAM *sort_param); int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ulonglong); my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows); +struct OPTIMIZER_COSTS; +void myisam_update_optimizer_costs(struct OPTIMIZER_COSTS *costs); #ifdef __cplusplus } diff --git a/mysql-test/include/analyze-format.inc b/mysql-test/include/analyze-format.inc index 7d1c48f3e6f..e65450ff001 100644 --- a/mysql-test/include/analyze-format.inc +++ b/mysql-test/include/analyze-format.inc @@ -1,3 +1,3 @@ # The time on ANALYSE FORMAT=JSON is rather variable ---replace_regex /("(r_total_time_ms|r_table_time_ms|r_other_time_ms|r_buffer_size|r_filling_time_ms|r_query_time_in_progress_ms)": )[^, \n]*/\1"REPLACED"/ +--replace_regex /("(r_total_time_ms|r_table_time_ms|r_other_time_ms|r_buffer_size|r_filling_time_ms|r_query_time_in_progress_ms|r_unpack_time_ms|cost)": )[^, \n]*/\1"REPLACED"/ diff --git a/mysql-test/include/analyze-no-filtered.inc b/mysql-test/include/analyze-no-filtered.inc new file mode 100644 index 00000000000..eb1663167b2 --- /dev/null +++ b/mysql-test/include/analyze-no-filtered.inc @@ -0,0 +1,2 @@ +--replace_regex /("(filtered|r_total_time_ms|r_table_time_ms|r_other_time_ms|r_buffer_size|r_filling_time_ms|r_query_time_in_progress_ms|r_unpack_time_ms|cost)": )[^, \n]*/\1"REPLACED"/ + diff --git a/mysql-test/include/common-tests.inc b/mysql-test/include/common-tests.inc index 9c6b29858c8..9b54b049f8b 100644 --- a/mysql-test/include/common-tests.inc +++ b/mysql-test/include/common-tests.inc @@ -13,6 +13,11 @@ drop table if exists t1,t2,t3,t4; --enable_warnings +# We have to use Aria instead of MyISAM as MyISAM has a very high row +# access cost which causes some tests to use use join_cache instead of eq_ref + +set @@default_storage_engine="aria"; + CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -1429,7 +1434,7 @@ set tmp_memory_table_size=default; select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10; # -# A big order by that should trigger a merge in filesort +# A big order by that should traigger a merge in filesort # select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2; @@ -1446,9 +1451,9 @@ select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr orde explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3; -# -# Some test with ORDER BY and limit -# +--echo # +--echo # Some test with ORDER BY and limit +--echo # explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; @@ -1501,7 +1506,7 @@ create table t4 ( companyname char(30) NOT NULL default '', PRIMARY KEY (companynr), UNIQUE KEY companyname(companyname) -) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +) ENGINE=aria MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; --disable_query_log INSERT INTO t4 (companynr, companyname) VALUES (29,'company 1'); @@ -1555,8 +1560,9 @@ explain select companynr,companyname from t2 left join t4 using (companynr) wher explain select companynr,companyname from t4 left join t2 using (companynr) where companynr is null; delete from t2 where fld1=999999; -# -# Test left join optimization +--echo # +--echo # Test left join optimization +--echo # explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc index 6c7ac3b69fe..00364fd3406 100644 --- a/mysql-test/include/ctype_numconv.inc +++ b/mysql-test/include/ctype_numconv.inc @@ -1739,6 +1739,7 @@ CREATE TABLE t1 ( date_column DATE DEFAULT NULL, KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); +INSERT INTO t1 VALUES (3,'2012-09-01'),(4,'2012-10-01'),(5,'2012-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; diff --git a/mysql-test/include/explain-no-costs-filtered.inc b/mysql-test/include/explain-no-costs-filtered.inc new file mode 100644 index 00000000000..585d8b3fdcc --- /dev/null +++ b/mysql-test/include/explain-no-costs-filtered.inc @@ -0,0 +1 @@ +--replace_regex /("(cost|filtered)": )[^, \n]*/\1"REPLACED"/ diff --git a/mysql-test/include/explain-no-costs.inc b/mysql-test/include/explain-no-costs.inc new file mode 100644 index 00000000000..f2f362b8cbe --- /dev/null +++ b/mysql-test/include/explain-no-costs.inc @@ -0,0 +1 @@ +--replace_regex /("(cost)": )[^, \n]*/\1"COST_REPLACED"/ diff --git a/mysql-test/include/explain_non_select.inc b/mysql-test/include/explain_non_select.inc index d22310c9813..8e60f582f9e 100644 --- a/mysql-test/include/explain_non_select.inc +++ b/mysql-test/include/explain_non_select.inc @@ -1,6 +1,7 @@ # This file is a collection of regression and coverage tests # for WL#4897: Add EXPLAIN INSERT/UPDATE/DELETE. +-- source include/have_sequence.inc -- disable_query_log -- disable_result_log # SET GLOBAL innodb_stats_persistent=0; @@ -73,15 +74,18 @@ INSERT INTO t2 VALUES (1), (2), (3); --source include/explain_utils.inc DROP TABLE t1, t2; ---echo #7 +--echo #7a CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); CREATE TABLE t2 (b INT); -INSERT INTO t2 VALUES (1), (2), (3); ---let $query = UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3) ---let $select = SELECT * FROM t1, t2 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3) +INSERT INTO t2 VALUES (1), (2), (3), (1000); +CREATE TABLE t3 like t2; +insert into t3 select * from t2; +insert into t3 select seq from seq_1001_to_2000; +--let $query = UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t3 WHERE t3.b < 3) +--let $select = SELECT * FROM t1, t2 WHERE a IN (SELECT b FROM t3 WHERE t3.b < 3) --source include/explain_utils.inc -DROP TABLE t1, t2; +DROP TABLE t1, t2, t3; --echo #8 CREATE TABLE t1 (a INT); @@ -197,7 +201,7 @@ DROP TABLE t1, t2, t3; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); CREATE TABLE t2 (a INT); -INSERT INTO t2 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (1), (2), (3), (1000); --let $query = UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2) --let $select = SELECT * FROM t1 WHERE a IN (SELECT a FROM t2) --source include/explain_utils.inc diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc index d78fe0dd209..b37f59b46c5 100644 --- a/mysql-test/include/icp_tests.inc +++ b/mysql-test/include/icp_tests.inc @@ -486,7 +486,7 @@ CREATE TABLE t1 ( ); INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1); - +insert into t1 select seq,seq from seq_100_to_110; EXPLAIN SELECT pk, c1 FROM t1 WHERE (pk<3 or pk>3); SET SESSION optimizer_switch='index_condition_pushdown=off'; @@ -723,7 +723,6 @@ DROP TABLE t1; CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b)); INSERT INTO t1 VALUES (1,4,'Ill'); -insert into t1 select seq+100,5,seq from seq_1_to_100; CREATE TABLE t2 (a varchar(1024), KEY (a(512))); INSERT INTO t2 VALUES @@ -856,6 +855,8 @@ ANALYZE TABLE t1,t2; SET @save_optimize_switch=@@optimizer_switch; SET optimizer_switch='materialization=on'; +set @save_optimizer_where_cost=@@optimizer_where_cost; +set @@optimizer_where_cost=1; EXPLAIN SELECT COUNT(*) FROM t1 AS t, t2 @@ -873,6 +874,7 @@ WHERE c = g OR a = 0 AND h < 'z' ); SET optimizer_switch=@save_optimizer_switch; +set @@optimizer_where_cost=@save_optimizer_where_cost; DROP TABLE t1,t2; diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index 91609f628ca..199fc9d3b2f 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -517,7 +517,7 @@ DROP TABLE t1; create table t1 (a int); insert into t1 values (1),(2); create table t2(a int, b int); -insert into t2 values (1,1), (2, 1000); +insert into t2 values (1,1), (2, 1000),(5000,5000); create table t3 (a int, b int, filler char(100), key(a), key(b)); insert into t3 select 1000, 1000,'filler' from seq_1_to_1000; diff --git a/mysql-test/include/last_query_cost.inc b/mysql-test/include/last_query_cost.inc new file mode 100644 index 00000000000..a18fd9e4c04 --- /dev/null +++ b/mysql-test/include/last_query_cost.inc @@ -0,0 +1,5 @@ +--disable_query_log +--disable_column_names +show status like 'last_query_cost'; +--enable_column_names +--enable_query_log diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 2ec0868c39e..cbb79668b2a 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -1183,14 +1183,14 @@ set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; set global innodb_autoextend_increment=8; set global innodb_autoextend_increment=@my_innodb_autoextend_increment; -# -# Bug #37830: ORDER BY ASC/DESC - no difference -# +--echo # +--echo # Bug #37830: ORDER BY ASC/DESC - no difference +--echo # CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b)) ENGINE=InnoDB; -INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1); +INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1), (100,2,2); INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1; -- disable_query_log diff --git a/mysql-test/include/percona_nonflushing_analyze_debug.inc b/mysql-test/include/percona_nonflushing_analyze_debug.inc index 95621c70d5c..8cdf6218609 100644 --- a/mysql-test/include/percona_nonflushing_analyze_debug.inc +++ b/mysql-test/include/percona_nonflushing_analyze_debug.inc @@ -8,7 +8,7 @@ --connect con1,localhost,root -SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; +SET DEBUG_SYNC="handler_rnd_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; send_eval SELECT * FROM $percona_nonflushing_analyze_table; diff --git a/mysql-test/include/rowid_filter_debug_kill.inc b/mysql-test/include/rowid_filter_debug_kill.inc index 513efed8a4c..c672954fc7c 100644 --- a/mysql-test/include/rowid_filter_debug_kill.inc +++ b/mysql-test/include/rowid_filter_debug_kill.inc @@ -2,13 +2,18 @@ --source include/have_debug_sync.inc --source include/have_sequence.inc --source include/count_sessions.inc +--source include/have_sequence.inc +--source include/no_valgrind_without_big.inc --echo # --echo # MDEV-22761 KILL QUERY during rowid_filter, crashes --echo # +create table t1(a int); +insert into t1 select seq from seq_1_to_1000; + create table t2(a int); -insert into t2 select * from seq_0_to_99; +insert into t2 select seq from seq_1_to_100; # 10K rows CREATE TABLE t3 ( @@ -18,22 +23,16 @@ CREATE TABLE t3 ( KEY (key1), KEY (key2) ); +insert into t3 select seq,seq, 'filler-data-filler-data' from seq_1_to_2000; + select engine from information_schema.tables where table_schema=database() and table_name='t3'; - -insert into t3 -select - A.seq, - B.seq, - 'filler-data-filler-data' -from seq_0_to_99 A, seq_0_to_99 B; - analyze table t2,t3; explain select * from t2, t3 where - t3.key1=t2.a and t3.key2 in (2,3); + t3.key1=t2.a and t3.key2 in (2,3,4,5,6,7,8,9,10); let $target_id= `select connection_id()`; @@ -41,7 +40,7 @@ set debug_sync='handler_rowid_filter_check SIGNAL at_rowid_filter_check WAIT_FOR send select * from t2, t3 where - t3.key1=t2.a and t3.key2 in (2,3); + t3.key1=t2.a and t3.key2 in (2,3,4,5,6,7,8,9,10); connect (con1, localhost, root,,); set debug_sync='now WAIT_FOR at_rowid_filter_check'; @@ -55,5 +54,5 @@ disconnect con1; reap; set debug_sync='RESET'; -drop table t2,t3; +drop table t1,t2,t3; --source include/wait_until_count_sessions.inc diff --git a/mysql-test/include/world.inc b/mysql-test/include/world.inc index 1e81c5c1aa7..a6f877ce0cd 100644 --- a/mysql-test/include/world.inc +++ b/mysql-test/include/world.inc @@ -4,6 +4,7 @@ # Table Country +BEGIN; INSERT IGNORE INTO Country VALUES ('AFG','Afghanistan',652090.00,22720000,1), ('NLD','Netherlands',41526.00,15864000,5), @@ -5339,5 +5340,6 @@ INSERT INTO CountryLanguage VALUES ('CHN','Dong',0.2), ('RUS','Belorussian',0.3), ('USA','Portuguese',0.2); +COMMIT; ANALYZE TABLE Country, City, CountryLanguage; diff --git a/mysql-test/main/alter_table_combinations,aria.rdiff b/mysql-test/main/alter_table_combinations,aria.rdiff index 9ea38135908..e030571679f 100644 --- a/mysql-test/main/alter_table_combinations,aria.rdiff +++ b/mysql-test/main/alter_table_combinations,aria.rdiff @@ -1,5 +1,5 @@ ---- main/alter_table_combinations.result 2022-05-24 17:16:56.769146869 +0200 -+++ main/alter_table_combinations.reject 2022-05-24 17:25:20.847126357 +0200 +--- main/alter_table_combinations.result ++++ main/alter_table_combinations.reject @@ -173,8 +173,7 @@ t3 CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL, diff --git a/mysql-test/main/alter_table_combinations,heap.rdiff b/mysql-test/main/alter_table_combinations,heap.rdiff index 0ca6d3de88d..493ce0ea884 100644 --- a/mysql-test/main/alter_table_combinations,heap.rdiff +++ b/mysql-test/main/alter_table_combinations,heap.rdiff @@ -1,5 +1,5 @@ ---- main/alter_table_combinations.result 2022-05-24 17:16:56.769146869 +0200 -+++ main/alter_table_combinations.reject 2022-05-24 17:25:01.216127156 +0200 +--- main/alter_table_combinations.result ++++ main/alter_table_combinations.reject @@ -11,7 +11,7 @@ alter table t1 change x xx int, algorithm=inplace; check table t1; diff --git a/mysql-test/main/analyze_format_json.result b/mysql-test/main/analyze_format_json.result index 9a756782f96..02635a8f3dd 100644 --- a/mysql-test/main/analyze_format_json.result +++ b/mysql-test/main/analyze_format_json.result @@ -10,6 +10,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -17,9 +18,11 @@ ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -46,6 +49,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -53,9 +57,11 @@ ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -72,9 +78,11 @@ ANALYZE "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t0.a"], + "loops": 10, "r_loops": 0, "rows": 1, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null } @@ -96,6 +104,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -103,9 +112,11 @@ ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -122,9 +133,11 @@ ANALYZE "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t0.a"], + "loops": 10, "r_loops": 10, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -149,6 +162,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -156,9 +170,11 @@ ANALYZE "table": { "table_name": "tbl1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 100, "r_rows": 100, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -171,9 +187,11 @@ ANALYZE "table": { "table_name": "tbl2", "access_type": "ALL", + "loops": 100, "r_loops": 1, "rows": 100, "r_rows": 100, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -183,7 +201,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "1Kb", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -198,6 +217,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -205,9 +225,11 @@ ANALYZE "table": { "table_name": "tbl1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 100, "r_rows": 100, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -220,9 +242,11 @@ ANALYZE "table": { "table_name": "tbl2", "access_type": "ALL", + "loops": 100, "r_loops": 1, "rows": 100, "r_rows": 100, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -233,7 +257,8 @@ ANALYZE "buffer_size": "1Kb", "join_type": "BNL", "attached_condition": "tbl1.c > tbl2.c", - "r_filtered": 15.83333333 + "r_filtered": 15.83333333, + "r_unpack_time_ms": "REPLACED" } } ] @@ -256,6 +281,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -263,9 +289,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -282,9 +310,11 @@ ANALYZE "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t1.a"], + "loops": 10, "r_loops": 10, - "rows": 2, + "rows": 1, "r_rows": 0.2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -317,6 +347,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -324,9 +355,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -381,6 +414,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -392,9 +426,11 @@ ANALYZE "key": "PRIMARY", "key_length": "4", "used_key_parts": ["pk"], + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -461,6 +497,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -468,9 +505,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 5, "r_rows": 5, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -494,9 +533,11 @@ ANALYZE "table_name": "t2", "access_type": "ALL", "possible_keys": ["key1", "key2", "key3", "key4"], + "loops": 5, "r_loops": 5, "rows": 1010, "r_rows": 203.8, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -531,6 +572,7 @@ ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -538,9 +580,11 @@ ANALYZE "table": { "table_name": "tbl1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -555,6 +599,7 @@ ANALYZE "query_block": { "select_id": 2, "operation": "UNION", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -562,9 +607,11 @@ ANALYZE "table": { "table_name": "tbl2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -602,6 +649,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "having_condition": "TOP > t2.a", @@ -619,9 +667,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 256, "r_rows": 256, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -642,6 +692,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "filesort": { @@ -658,9 +709,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 256, "r_rows": 256, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -695,6 +748,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "filesort": { @@ -711,9 +765,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 256, "r_rows": 256, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -741,6 +797,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -748,9 +805,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -762,9 +821,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 2, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -775,7 +836,8 @@ ANALYZE "buffer_size": "65", "join_type": "BNL", "attached_condition": "(t2.b,t2.b in (subquery#2))", - "r_filtered": null + "r_filtered": null, + "r_unpack_time_ms": "REPLACED" } } ], @@ -783,6 +845,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -790,9 +853,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -805,6 +870,8 @@ ANALYZE ] } } +SELECT STRAIGHT_JOIN * FROM t1, t2 WHERE b IN ( SELECT a FROM t1 ); +a b drop table t1,t2; # # MDEV-8864: Server crash #2 in Item_field::print on ANALYZE FORMAT=JSON @@ -827,6 +894,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "filesort": { @@ -852,9 +920,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -866,9 +936,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 2, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -878,7 +950,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "1", "join_type": "BNL", - "r_filtered": null + "r_filtered": null, + "r_unpack_time_ms": "REPLACED" } } ], @@ -889,14 +962,17 @@ ANALYZE "r_loops": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 2, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null } @@ -906,9 +982,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 2, "r_loops": 0, "rows": 2, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null }, @@ -916,7 +994,8 @@ ANALYZE "buffer_size": "65", "join_type": "BNL", "attached_condition": "t2.f2 = t3.f3", - "r_filtered": null + "r_filtered": null, + "r_unpack_time_ms": "REPLACED" } } ] @@ -947,6 +1026,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -954,9 +1034,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -972,6 +1054,7 @@ ANALYZE "r_loops": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -986,9 +1069,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 10, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null, "attached_condition": "t2.a < t1.a" diff --git a/mysql-test/main/analyze_format_json.test b/mysql-test/main/analyze_format_json.test index 3f3324e9eec..84625f125fb 100644 --- a/mysql-test/main/analyze_format_json.test +++ b/mysql-test/main/analyze_format_json.test @@ -154,6 +154,7 @@ drop table t0, t1; --echo # --echo # MDEV-7970: EXPLAIN FORMAT=JSON does not print HAVING +--source include/explain-no-costs.inc --echo # create table t0(a int); insert into t0 values (0),(1),(2),(3); @@ -190,6 +191,7 @@ INSERT INTO t2 VALUES (3),(4); --source include/analyze-format.inc ANALYZE FORMAT=JSON SELECT STRAIGHT_JOIN * FROM t1, t2 WHERE b IN ( SELECT a FROM t1 ); +SELECT STRAIGHT_JOIN * FROM t1, t2 WHERE b IN ( SELECT a FROM t1 ); drop table t1,t2; diff --git a/mysql-test/main/analyze_stmt.result b/mysql-test/main/analyze_stmt.result index c5d35759c9c..8ba089d8d31 100644 --- a/mysql-test/main/analyze_stmt.result +++ b/mysql-test/main/analyze_stmt.result @@ -258,7 +258,7 @@ drop table t1; create table t1 (i int); analyze delete from t1 returning *; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 0 0.00 100.00 100.00 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE drop table t1; # # MDEV-6396: ANALYZE INSERT/REPLACE is accepted, but does not produce a plan @@ -314,7 +314,7 @@ insert into t2 values (0),(1); analyze select * from t1 straight_join t2 force index(a) where t2.a=t1.a; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10.00 100.00 100.00 Using where -1 SIMPLE t2 ref a a 5 test.t1.a 2 0.20 100.00 100.00 Using index +1 SIMPLE t2 ref a a 5 test.t1.a 1 0.20 100.00 100.00 Using index drop table t1,t2; # # MDEV-8063: Unconditional ANALYZE DELETE does not delete rows diff --git a/mysql-test/main/analyze_stmt_orderby.result b/mysql-test/main/analyze_stmt_orderby.result index 76bc4d964b8..c3a3f2c562e 100644 --- a/mysql-test/main/analyze_stmt_orderby.result +++ b/mysql-test/main/analyze_stmt_orderby.result @@ -182,6 +182,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t2.b", "temporary_table": { @@ -190,7 +191,9 @@ EXPLAIN "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t0.a is not null" } @@ -204,7 +207,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t0.a"], + "loops": 10, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -222,6 +227,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "filesort": { @@ -238,9 +244,11 @@ ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -257,9 +265,11 @@ ANALYZE "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t0.a"], + "loops": 10, "r_loops": 10, "rows": 1, "r_rows": 0.4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -285,6 +295,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -293,7 +304,9 @@ EXPLAIN "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t0.a is not null" } @@ -309,7 +322,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t0.a"], + "loops": 10, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -325,6 +340,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -342,9 +358,11 @@ ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -363,9 +381,11 @@ ANALYZE "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t0.a"], + "loops": 10, "r_loops": 10, "rows": 1, "r_rows": 0.4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -396,6 +416,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "filesort": { @@ -412,9 +433,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 1000, "r_rows": 1000, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -459,6 +482,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "duplicate_removal": { @@ -468,9 +492,11 @@ ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -482,9 +508,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 10, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -494,7 +522,8 @@ ANALYZE "buffer_size": "65", "join_type": "BNL", "attached_condition": "t3.a = t0.a", - "r_filtered": 10 + "r_filtered": 10, + "r_unpack_time_ms": "REPLACED" } } ] @@ -526,6 +555,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "filesort": { @@ -551,9 +581,11 @@ ANALYZE "table": { "table_name": "t6", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 5, "r_rows": 5, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -566,9 +598,11 @@ ANALYZE "table": { "table_name": "t5", "access_type": "ALL", + "loops": 5, "r_loops": 1, "rows": 7, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -578,7 +612,8 @@ ANALYZE "buffer_size": "119", "join_type": "BNL", "attached_condition": "t5.a = t6.a", - "r_filtered": 21.42857143 + "r_filtered": 21.42857143, + "r_unpack_time_ms": "REPLACED" } } ] @@ -596,6 +631,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "count(distinct t5.b)", "temporary_table": { @@ -607,7 +643,9 @@ EXPLAIN "table": { "table_name": "t6", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t6.b > 0 and t6.a <= 5" } @@ -617,7 +655,9 @@ EXPLAIN "table": { "table_name": "t5", "access_type": "ALL", + "loops": 5, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -664,6 +704,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -674,9 +715,11 @@ ANALYZE "key": "idx", "key_length": "5", "used_key_parts": ["col1"], + "loops": 1, "r_loops": 1, "rows": 7, "r_rows": 20, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, diff --git a/mysql-test/main/analyze_stmt_orderby.test b/mysql-test/main/analyze_stmt_orderby.test index ecee8040ed5..519cae45a97 100644 --- a/mysql-test/main/analyze_stmt_orderby.test +++ b/mysql-test/main/analyze_stmt_orderby.test @@ -21,6 +21,7 @@ insert into t2 select A.a*1000 + B.a, A.a*1000 + B.a from t0 A, t1 B; --echo # explain update t2 set b=b+1 order by b limit 5; +--source include/explain-no-costs.inc explain format=json update t2 set b=b+1 order by b limit 5; --source include/analyze-format.inc @@ -32,6 +33,7 @@ update t2 set b=b+1 order by b limit 5; --echo # explain update t2 set a=a+1 where a<10; +--source include/explain-no-costs.inc explain format=json update t2 set a=a+1 where a<10; --source include/analyze-format.inc @@ -43,6 +45,7 @@ update t2 set a=a+1 where a<10; --echo # explain delete from t2 order by b limit 5; +--source include/explain-no-costs.inc explain format=json delete from t2 order by b limit 5; --source include/analyze-format.inc @@ -54,6 +57,7 @@ delete from t2 order by b limit 5; --echo # explain select * from t0,t2 where t2.a=t0.a order by t2.b limit 4; +--source include/explain-no-costs.inc explain format=json select * from t0,t2 where t2.a=t0.a order by t2.b limit 4; --source include/analyze-format.inc @@ -66,6 +70,7 @@ select * from t0,t2 where t2.a=t0.a order by t2.b limit 4; --echo # explain select * from t0,t2 where t2.a=t0.a order by t0.a limit 4; +--source include/explain-no-costs.inc explain format=json select * from t0,t2 where t2.a=t0.a order by t0.a limit 4; --source include/analyze-format.inc @@ -143,6 +148,7 @@ select count(distinct t5.b) as sum from t5, t6 where t5.a=t6.a and t6.b > 0 and t5.a <= 5 group by t5.a order by sum limit 1; +--source include/explain-no-costs.inc explain format=json select count(distinct t5.b) as sum from t5, t6 where t5.a=t6.a and t6.b > 0 and t5.a <= 5 diff --git a/mysql-test/main/analyze_stmt_privileges2.result b/mysql-test/main/analyze_stmt_privileges2.result index 2b75f736a22..0dec4722802 100644 --- a/mysql-test/main/analyze_stmt_privileges2.result +++ b/mysql-test/main/analyze_stmt_privileges2.result @@ -377,13 +377,11 @@ a b EXPLAIN SELECT * FROM t1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM t1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 4.00 100.00 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 0.00 100.00 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 3.00 100.00 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 3.00 100.00 0.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #------------------------------------------------------------------------ # I/R/U/D/S on the inner view # Expectation: Can run everything @@ -492,13 +490,11 @@ a b EXPLAIN SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 8.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #------------------------------------------------------------------------ # I/R/U/D/S on the outer view # Expectation: Can run everything @@ -599,13 +595,11 @@ a b EXPLAIN SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 12 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 12 12.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #======================================================================== # Test: Grant INSERT on the table @@ -1445,10 +1439,10 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f DELETE FROM t1 WHERE a = 10; EXPLAIN DELETE FROM t1 WHERE a = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE ANALYZE DELETE FROM t1 WHERE a = 10; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 0.00 100.00 100.00 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DELETE FROM t1 USING t1, t2; EXPLAIN DELETE FROM t1 USING t1, t2; id select_type table type possible_keys key key_len ref rows Extra @@ -1592,13 +1586,11 @@ a b EXPLAIN SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 4.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #------------------------------------------------------------------------ # I/R/U/D/S on the outer view # Expectation: Can run everything: SELECT access to the column `a` @@ -1709,13 +1701,11 @@ a b EXPLAIN SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 8.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #======================================================================== # Test: Grant SELECT, INSERT, UPDATE, DELETE on the table @@ -1790,10 +1780,10 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f DELETE FROM t1 WHERE a = 10; EXPLAIN DELETE FROM t1 WHERE a = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE ANALYZE DELETE FROM t1 WHERE a = 10; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 0.00 100.00 100.00 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DELETE FROM t1 USING t1, t2; EXPLAIN DELETE FROM t1 USING t1, t2; id select_type table type possible_keys key key_len ref rows Extra @@ -1941,13 +1931,11 @@ a b EXPLAIN SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 4.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #------------------------------------------------------------------------ # I/R/U/D/S on the outer view # Expectation: Can run everything @@ -2049,13 +2037,11 @@ a b EXPLAIN SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 8.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ######################################################################### # Inner view permission tests @@ -2698,13 +2684,11 @@ a b EXPLAIN SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 14 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 14 14.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #------------------------------------------------------------------------ # I/R/U/D/S on the outer view # Expectation: Can run everything @@ -2805,13 +2789,11 @@ a b EXPLAIN SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 18 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 18 18.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #======================================================================== # Test: Grant INSERT on the inner view @@ -3988,13 +3970,11 @@ a b EXPLAIN SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 35 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v1 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 35 35.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #------------------------------------------------------------------------ # I/R/U/D/S on the outer view # Expectation: Can run everything @@ -4095,13 +4075,11 @@ a b EXPLAIN SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 39 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 39 39.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ######################################################################### # Outer view permission tests @@ -4615,13 +4593,11 @@ a b EXPLAIN SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 39 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 39 39.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) #======================================================================== # Test: Grant INSERT on the outer view @@ -5222,13 +5198,11 @@ a b EXPLAIN SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 44 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) ANALYZE SELECT * FROM v2 WHERE a IN ( SELECT a FROM t2 ); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 44 44.00 100.00 0.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 NULL 100.00 NULL -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 NULL 100.00 NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) disconnect con1; connection default; DROP USER 'privtest'@localhost; diff --git a/mysql-test/main/brackets.result b/mysql-test/main/brackets.result index f87afdc0f47..0403ce81d1d 100644 --- a/mysql-test/main/brackets.result +++ b/mysql-test/main/brackets.result @@ -261,6 +261,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -269,7 +270,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -291,6 +294,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -299,7 +303,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -329,12 +335,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 20" } @@ -346,12 +355,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -383,12 +395,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 20" } @@ -400,12 +415,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -445,6 +463,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -453,7 +472,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -466,12 +487,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.pk > 4" } diff --git a/mysql-test/main/brackets.test b/mysql-test/main/brackets.test index 9a0c204e271..4300e8a0592 100644 --- a/mysql-test/main/brackets.test +++ b/mysql-test/main/brackets.test @@ -117,24 +117,28 @@ let $q1= select a from t1 order by a desc limit 1; eval $q1; eval explain extended $q1; +--source include/explain-no-costs.inc eval explain format=json $q1; let $q2= (select a from t1 order by a desc) limit 1; eval $q2; eval explain extended $q2; +--source include/explain-no-costs.inc eval explain format=json $q2; let $q1= (select a from t1 where a=20 union select a from t1) order by a desc limit 1; eval $q1; eval explain extended $q1; +--source include/explain-no-costs.inc eval explain format=json $q1; let $q2= ((select a from t1 where a=20 union select a from t1) order by a desc) limit 1; eval $q2; eval explain extended $q2; +--source include/explain-no-costs.inc eval explain format=json $q2; drop table t1; @@ -150,6 +154,7 @@ let $q= ((select * from t1 order by pk) limit 2) union (select * from t1 where pk > 4); eval $q; eval explain extended $q; +--source include/explain-no-costs.inc eval explain format=json $q; drop table t1; diff --git a/mysql-test/main/bug12427262.result b/mysql-test/main/bug12427262.result index 6e79ec3aa11..8ec14efc45e 100644 --- a/mysql-test/main/bug12427262.result +++ b/mysql-test/main/bug12427262.result @@ -16,8 +16,6 @@ create table t10 (c1 int); select Sum(ALL(COUNT_READ)) from performance_schema.file_summary_by_instance where FILE_NAME like "%show_table_lw_db%" AND FILE_NAME like "%.frm%" AND EVENT_NAME='wait/io/file/sql/FRM' into @count_read_before; -Warnings: -Warning 1287 ' INTO FROM...' instead show tables; Tables_in_show_table_lw_db t1 @@ -33,8 +31,6 @@ t9 select Sum(ALL(COUNT_READ)) from performance_schema.file_summary_by_instance where FILE_NAME like "%show_table_lw_db%" AND FILE_NAME like "%.frm%" AND EVENT_NAME='wait/io/file/sql/FRM' into @count_read_after; -Warnings: -Warning 1287 ' INTO FROM...' instead select @count_read_after-@count_read_before; @count_read_after-@count_read_before 0.00000000000000000000000000000000000000 @@ -53,8 +49,6 @@ t9 BASE TABLE select Sum(ALL(COUNT_READ)) from performance_schema.file_summary_by_instance where FILE_NAME like "%show_table_lw_db%" AND FILE_NAME like "%.frm%" AND EVENT_NAME='wait/io/file/sql/FRM' into @count_read_after; -Warnings: -Warning 1287 ' INTO FROM...' instead select @count_read_after-@count_read_before; @count_read_after-@count_read_before 10.00000000000000000000000000000000000000 diff --git a/mysql-test/main/comments.result b/mysql-test/main/comments.result index 8b3f9fba382..506c31b07b6 100644 --- a/mysql-test/main/comments.result +++ b/mysql-test/main/comments.result @@ -67,6 +67,9 @@ SELECT 1 /*!100000 +1*/; SELECT 1 /*!210000 +1*/; 1 1 +SELECT 1 /*!190000 +1*/; +1 +1 # # Tesing that versions >= 5.7.x and < 10.0.0 are not ignored # when used with the MariaDB executable comment syntax. @@ -89,6 +92,9 @@ SELECT 1 /*M!100000 +1*/; SELECT 1 /*M!210000 +1*/; 1 1 +SELECT 1 /*M!190000 +1*/; +1 +1 select 1/*!2*/; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '2*/' at line 1 select 1/*!0000002*/; diff --git a/mysql-test/main/comments.test b/mysql-test/main/comments.test index 87125890780..42cdc4255fd 100644 --- a/mysql-test/main/comments.test +++ b/mysql-test/main/comments.test @@ -42,6 +42,7 @@ SELECT 1 /*!50999 +1*/; SELECT 1 /*!99999 +1*/; SELECT 1 /*!100000 +1*/; SELECT 1 /*!210000 +1*/; +SELECT 1 /*!190000 +1*/; --echo # --echo # Tesing that versions >= 5.7.x and < 10.0.0 are not ignored @@ -53,6 +54,7 @@ SELECT 1 /*M!50999 +1*/; SELECT 1 /*M!99999 +1*/; SELECT 1 /*M!100000 +1*/; SELECT 1 /*M!210000 +1*/; +SELECT 1 /*M!190000 +1*/; # # Bug#25411 (trigger code truncated) diff --git a/mysql-test/main/compress.result b/mysql-test/main/compress.result index 24979346149..f5c85d3eb6f 100644 --- a/mysql-test/main/compress.result +++ b/mysql-test/main/compress.result @@ -6,6 +6,7 @@ select * from information_schema.session_status where variable_name= 'COMPRESSIO VARIABLE_NAME VARIABLE_VALUE COMPRESSION ON drop table if exists t1,t2,t3,t4; +set @@default_storage_engine="aria"; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -606,6 +607,9 @@ explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +# +# Some test with ORDER BY and limit +# explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort @@ -1295,7 +1299,7 @@ companynr tinyint(2) unsigned zerofill NOT NULL default '00', companyname char(30) NOT NULL default '', PRIMARY KEY (companynr), UNIQUE KEY companyname(companyname) -) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +) ENGINE=aria MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; companynr companyname 00 Unknown @@ -1385,6 +1389,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t2 where fld1=999999; +# +# Test left join optimization +# explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where @@ -1399,15 +1406,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; id select_type table type possible_keys key key_len ref rows Extra @@ -1423,11 +1430,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/costs.result b/mysql-test/main/costs.result new file mode 100644 index 00000000000..9d69207f956 --- /dev/null +++ b/mysql-test/main/costs.result @@ -0,0 +1,126 @@ +create table t1 (a int primary key, b int, c int, d int, e int, key ba (b,a), key bda (b,d,a), key cba (c,b,a), key cb (c,b), key d (d)) engine=aria; +insert into t1 select seq,seq,seq,seq,seq from seq_1_to_10; +insert into t1 values(20,2,2,2,2),(21,3,4,5,6); +# +# Get different scan costs +# +explain select sum(e) as "table_scan" from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 12 +Last_query_cost 0.012556 +explain select sum(a) as "index scan" from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 12 Using index +Last_query_cost 0.007441 +# +# Range scans should be used if we don't examine all rows in the table +# +explain select count(a) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +Last_query_cost 0.000000 +explain select count(*) from t1 where a > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 12 Using where; Using index +Last_query_cost 0.002877 +explain select count(*) from t1 where a > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 12 Using where; Using index +Last_query_cost 0.002877 +explain select count(*) from t1 where a > 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 11 Using where; Using index +Last_query_cost 0.002747 +# +# Shorter indexes are prefered over longer indexs +# +explain select sum(a+b) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL ba 9 NULL 12 Using index +Last_query_cost 0.007441 +explain select count(*) from t1 where b between 5 and 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ba,bda ba 5 NULL 6 Using where; Using index +Last_query_cost 0.002097 +explain select sum(b+c) from t1 where b between 5 and 6 and c between 5 and 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ba,bda,cba,cb cba 10 NULL 2 Using where; Using index +Last_query_cost 0.001577 +# Cost of 'd' should be slightly smaller as key 'ba' is longer than 'd' +explain select count(*) from t1 where b > 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ba,bda ba 5 NULL 5 Using where; Using index +Last_query_cost 0.001967 +explain select count(*) from t1 where d > 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range d d 5 NULL 5 Using where; Using index +Last_query_cost 0.001967 +# +# Check covering index usage +# +explain select a,b,c from t1 where a=b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL cba 14 NULL 12 Using where; Using index +Last_query_cost 0.007441 +# +# Prefer ref keys over ranges +# +explain select count(*) from t1 where b=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref ba,bda ba 5 const 2 Using index +Last_query_cost 0.001141 +explain select count(*) from t1 where b=2 and c=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref ba,bda,cba,cb cba 10 const,const 2 Using index +Last_query_cost 0.001141 +explain select count(*) from t1 where b=3 and c between 3 and 4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ba,bda,cba,cb cba 10 NULL 2 Using where; Using index +Last_query_cost 0.001577 +# +# Prefer eq keys over ref keys +# +explain select a,b,e from t1 where a=10 or a=11; +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 +Last_query_cost 0.003126 +explain select a,b,e from t1 where d=10 or d=11; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range d d 5 NULL 2 Using index condition +Last_query_cost 0.003291 +drop table t1; +# +# MDEV-30328 Assertion `avg_io_cost != 0.0 || index_cost.io + row_cost.io == 0' failed in +# Cost_estimate::total_cost() +# +set @save=@@InnoDB.optimizer_disk_read_ratio; +set global InnoDB.optimizer_disk_read_ratio=0; +create table t1 ( +`l_orderkey` int(11) NOT NULL, +`l_partkey` int(11) DEFAULT NULL, +`l_suppkey` int(11) DEFAULT NULL, +`l_linenumber` int(11) NOT NULL, +`l_extra` int(11) NOT NULL, +`l_quantity` double DEFAULT NULL, +`l_extendedprice` double DEFAULT NULL, +`l_discount` double DEFAULT NULL, +`l_tax` double DEFAULT NULL, +`l_returnflag` char(1) DEFAULT NULL, +`l_linestatus` char(1) DEFAULT NULL, +`l_shipDATE` date DEFAULT NULL, +`l_commitDATE` date DEFAULT NULL, +`l_receiptDATE` date DEFAULT NULL, +`l_shipinstruct` char(25) DEFAULT NULL, +`l_shipmode` char(10) DEFAULT NULL, +`l_comment` varchar(44) DEFAULT NULL, +PRIMARY KEY (`l_orderkey`), +UNIQUE (`l_linenumber`), +UNIQUE (`l_extra`) , +KEY `l_suppkey` (l_suppkey, l_partkey), +KEY `long_suppkey` (l_partkey, l_suppkey, l_linenumber, l_extra) ) +ENGINE= InnoDB; +explain select count(*) from test.t1 force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range l_suppkey l_suppkey 10 NULL 1 Using where; Using index +drop table t1; +set global InnoDB.optimizer_disk_read_ratio=@save; diff --git a/mysql-test/main/costs.test b/mysql-test/main/costs.test new file mode 100644 index 00000000000..bb933a200db --- /dev/null +++ b/mysql-test/main/costs.test @@ -0,0 +1,116 @@ +# +# Test of cost calculations. This test is using the Aria engine as the cost +# calculations are stable for it. +# +# This file also includes MDEV's that shows errors in cost calculation functions. +# + +--source include/have_sequence.inc +--source include/have_innodb.inc + +create table t1 (a int primary key, b int, c int, d int, e int, key ba (b,a), key bda (b,d,a), key cba (c,b,a), key cb (c,b), key d (d)) engine=aria; +insert into t1 select seq,seq,seq,seq,seq from seq_1_to_10; +insert into t1 values(20,2,2,2,2),(21,3,4,5,6); + +--echo # +--echo # Get different scan costs +--echo # + +explain select sum(e) as "table_scan" from t1; +--source include/last_query_cost.inc +explain select sum(a) as "index scan" from t1; +--source include/last_query_cost.inc + +--echo # +--echo # Range scans should be used if we don't examine all rows in the table +--echo # +explain select count(a) from t1; +--source include/last_query_cost.inc +explain select count(*) from t1 where a > 0; +--source include/last_query_cost.inc +explain select count(*) from t1 where a > 1; +--source include/last_query_cost.inc +explain select count(*) from t1 where a > 2; +--source include/last_query_cost.inc + +--echo # +--echo # Shorter indexes are prefered over longer indexs +--echo # +explain select sum(a+b) from t1; +--source include/last_query_cost.inc +explain select count(*) from t1 where b between 5 and 10; +--source include/last_query_cost.inc +explain select sum(b+c) from t1 where b between 5 and 6 and c between 5 and 6; +--source include/last_query_cost.inc + +--echo # Cost of 'd' should be slightly smaller as key 'ba' is longer than 'd' +explain select count(*) from t1 where b > 6; +--source include/last_query_cost.inc +explain select count(*) from t1 where d > 6; +--source include/last_query_cost.inc + + +--echo # +--echo # Check covering index usage +--echo # +explain select a,b,c from t1 where a=b; +--source include/last_query_cost.inc + +--echo # +--echo # Prefer ref keys over ranges +--echo # + +explain select count(*) from t1 where b=2; +--source include/last_query_cost.inc +explain select count(*) from t1 where b=2 and c=2; +--source include/last_query_cost.inc +explain select count(*) from t1 where b=3 and c between 3 and 4; +--source include/last_query_cost.inc + +--echo # +--echo # Prefer eq keys over ref keys +--echo # + +explain select a,b,e from t1 where a=10 or a=11; +--source include/last_query_cost.inc +explain select a,b,e from t1 where d=10 or d=11; +--source include/last_query_cost.inc + +drop table t1; + +--echo # +--echo # MDEV-30328 Assertion `avg_io_cost != 0.0 || index_cost.io + row_cost.io == 0' failed in +--echo # Cost_estimate::total_cost() +--echo # + +set @save=@@InnoDB.optimizer_disk_read_ratio; +set global InnoDB.optimizer_disk_read_ratio=0; + +create table t1 ( + `l_orderkey` int(11) NOT NULL, + `l_partkey` int(11) DEFAULT NULL, + `l_suppkey` int(11) DEFAULT NULL, + `l_linenumber` int(11) NOT NULL, + `l_extra` int(11) NOT NULL, + `l_quantity` double DEFAULT NULL, + `l_extendedprice` double DEFAULT NULL, + `l_discount` double DEFAULT NULL, + `l_tax` double DEFAULT NULL, + `l_returnflag` char(1) DEFAULT NULL, + `l_linestatus` char(1) DEFAULT NULL, + `l_shipDATE` date DEFAULT NULL, + `l_commitDATE` date DEFAULT NULL, + `l_receiptDATE` date DEFAULT NULL, + `l_shipinstruct` char(25) DEFAULT NULL, + `l_shipmode` char(10) DEFAULT NULL, + `l_comment` varchar(44) DEFAULT NULL, + PRIMARY KEY (`l_orderkey`), + UNIQUE (`l_linenumber`), + UNIQUE (`l_extra`) , + KEY `l_suppkey` (l_suppkey, l_partkey), + KEY `long_suppkey` (l_partkey, l_suppkey, l_linenumber, l_extra) ) + ENGINE= InnoDB; +explain select count(*) from test.t1 force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0; +drop table t1; + +set global InnoDB.optimizer_disk_read_ratio=@save; diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index f7871d4f929..5989abb7324 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -85,14 +85,14 @@ with t as (select a, count(*) from t1 where b >= 'c' group by a) select * from t2,t where t2.c=t.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY ref key0 key0 5 test.t2.c 2 +1 PRIMARY ref key0 key0 5 test.t2.c 1 2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort explain select * from t2, (select a, count(*) from t1 where b >= 'c' group by a) as t where t2.c=t.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY ref key0 key0 5 test.t2.c 2 +1 PRIMARY ref key0 key0 5 test.t2.c 1 2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort # specivication of t contains having with t as (select a, count(*) from t1 where b >= 'c' @@ -150,16 +150,14 @@ explain with t as (select a from t1 where a<5) select * from t2 where c in (select a from t); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; FirstMatch(t2); Using join buffer (flat, BNL join) explain select * from t2 where c in (select a from (select a from t1 where a<5) as t); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; FirstMatch(t2); Using join buffer (flat, BNL join) # materialized t is used in a subquery with t as (select count(*) as c from t1 where b >= 'c' group by a) select * from t2 where c in (select c from t); @@ -175,7 +173,7 @@ with t as (select count(*) as c from t1 where b >= 'c' group by a) select * from t2 where c in (select c from t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY ref key0 key0 8 test.t2.c 2 Using where; FirstMatch(t2) +1 PRIMARY ref key0 key0 8 test.t2.c 1 Using where; FirstMatch(t2) 2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort explain select * from t2 @@ -183,7 +181,7 @@ where c in (select c from (select count(*) as c from t1 where b >= 'c' group by a) as t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY ref key0 key0 8 test.t2.c 2 Using where; FirstMatch(t2) +1 PRIMARY eq_ref distinct_key distinct_key 8 test.t2.c 1 Using where 3 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort # two references to t specified by a query # selecting a field: both in main query @@ -369,7 +367,7 @@ select c as a from t2 where c < 4) select * from t2,t where t2.c=t.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY ref key0 key0 5 test.t2.c 1 +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t2.c 1 2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where 3 UNION t2 ALL NULL NULL NULL NULL 4 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -381,7 +379,7 @@ select c as a from t2 where c < 4) as t where t2.c=t.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY ref key0 key0 5 test.t2.c 1 +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t2.c 1 2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where 3 UNION t2 ALL NULL NULL NULL NULL 4 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -597,7 +595,7 @@ explain select * from v2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY ref key0 key0 5 test.t2.c 2 +1 PRIMARY ref key0 key0 5 test.t2.c 1 2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort # with clause in the specification of a view that whose definition # table alias for a with table @@ -2300,14 +2298,14 @@ WHERE col1 IN ( SELECT col FROM t ); SELECT * FROM tt; col2 2018-10-01 -2018-10-01 2017-10-01 +2018-10-01 SELECT t4.col1 FROM tt, t4 WHERE t4.col2 = tt.col2 AND t4.col1 IN ( SELECT col FROM t ); col1 -8 4 +8 DROP TABLE t,tt; CALL SP1(); col1 diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result index 31bc12f2332..7114ff1e072 100644 --- a/mysql-test/main/cte_recursive.result +++ b/mysql-test/main/cte_recursive.result @@ -689,17 +689,17 @@ from ancestor_couple_ids c, coupled_ancestors h, coupled_ancestors w where c.h_id = h.id and c.w_id= w.id; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY ALL NULL NULL NULL NULL 2 100.00 Using where -1 PRIMARY ref key0 key0 5 c.h_id 2 100.00 -1 PRIMARY ref key0 key0 5 c.w_id 2 100.00 +1 PRIMARY ref key0 key0 5 c.h_id 1 100.00 +1 PRIMARY ref key0 key0 5 c.w_id 1 100.00 3 DERIVED folks ALL NULL NULL NULL NULL 12 100.00 Using where -4 RECURSIVE UNION ALL NULL NULL NULL NULL 2 100.00 -4 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join) -5 RECURSIVE UNION ALL NULL NULL NULL NULL 2 100.00 -5 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join) +4 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where +4 RECURSIVE UNION ref key0 key0 5 test.p.id 1 100.00 +5 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where +5 RECURSIVE UNION ref key0 key0 5 test.p.id 1 100.00 NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL 2 DERIVED ALL NULL NULL NULL NULL 12 100.00 Using where Warnings: -Note 1003 with recursive ancestor_couple_ids(`h_id`,`w_id`) as (/* select#2 */ select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors(`id`,`name`,`dob`,`father`,`mother`) as (/* select#3 */ select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all /* select#4 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `test`.`p`.`id` = `fa`.`h_id` union all /* select#5 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `test`.`p`.`id` = `ma`.`w_id`)/* select#1 */ select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id` +Note 1003 with recursive ancestor_couple_ids(`h_id`,`w_id`) as (/* select#2 */ select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors(`id`,`name`,`dob`,`father`,`mother`) as (/* select#3 */ select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all /* select#4 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `fa`.`h_id` = `test`.`p`.`id` union all /* select#5 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `ma`.`w_id` = `test`.`p`.`id`)/* select#1 */ select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id` # simple mutual recursion with recursive ancestor_couple_ids(h_id, w_id) @@ -1238,9 +1238,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 12 2 DERIVED folks ALL NULL NULL NULL NULL 12 Using where 3 RECURSIVE UNION p ALL PRIMARY NULL NULL NULL 12 -3 RECURSIVE UNION ref key0 key0 5 test.p.id 2 +3 RECURSIVE UNION ref key0 key0 5 test.p.id 1 4 RECURSIVE UNION p ALL PRIMARY NULL NULL NULL 12 -4 RECURSIVE UNION ref key0 key0 5 test.p.id 2 +4 RECURSIVE UNION ref key0 key0 5 test.p.id 1 NULL UNION RESULT ALL NULL NULL NULL NULL NULL with recursive ancestors @@ -1339,12 +1339,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 24, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -1355,12 +1358,15 @@ EXPLAIN { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "folks", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "folks.`name` = 'Me2'" } @@ -1372,12 +1378,15 @@ EXPLAIN "query_block": { "select_id": 6, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "prev_gen.`id` < 345", "materialized": { @@ -1389,12 +1398,15 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "folks", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "folks.`name` = 'Me'" } @@ -1406,13 +1418,16 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "folks", "access_type": "ALL", "possible_keys": ["PRIMARY"], + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1421,7 +1436,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 12, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -1446,12 +1463,15 @@ EXPLAIN "query_block": { "select_id": 5, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 24, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "ancestors.`id` < 234" } @@ -1499,12 +1519,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -1515,12 +1538,15 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "v", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.`name` = 'Me' and v.father is not null and v.mother is not null" } @@ -1534,7 +1560,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["id"], "ref": ["test.v.father"], + "loops": 12, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1547,7 +1575,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["id"], "ref": ["test.v.mother"], + "loops": 12, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1558,12 +1588,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "a.father is not null and a.mother is not null" } @@ -1577,7 +1610,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["id"], "ref": ["a.father"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1590,7 +1625,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["id"], "ref": ["a.mother"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1824,12 +1861,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -1840,12 +1880,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1856,12 +1899,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a < 1000" } @@ -2460,6 +2506,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -2467,9 +2514,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -2494,6 +2543,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "UNION", + "cost": "REPLACED", "r_loops": 10, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -2501,9 +2551,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 10, "rows": 2, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3158,7 +3210,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY ALL NULL NULL NULL NULL 16 100.00 2 DERIVED a ALL NULL NULL NULL NULL 16 100.00 Using where 3 RECURSIVE UNION b ALL NULL NULL NULL NULL 16 100.00 Using where -3 RECURSIVE UNION ref key0 key0 35 test.b.departure 2 100.00 +3 RECURSIVE UNION ref key0 key0 35 test.b.departure 1 100.00 4 DEPENDENT SUBQUERY ALL NULL NULL NULL NULL 16 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -3261,9 +3313,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 15 Using filesort 2 DERIVED t2 ALL NULL NULL NULL NULL 15 Using where 3 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 15 Using where -3 RECURSIVE UNION ref key0 key0 5 test.t2.id 2 +3 RECURSIVE UNION ref key0 key0 5 test.t2.id 1 4 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 15 Using where -4 RECURSIVE UNION ref key0 key0 5 test.t2.id 2 +4 RECURSIVE UNION ref key0 key0 5 test.t2.id 1 NULL UNION RESULT ALL NULL NULL NULL NULL NULL DROP TABLE t1,t2; set tmp_memory_table_size=default; @@ -3854,8 +3906,8 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where 1 PRIMARY ref key0 key0 23 test.t1.a1 1 FirstMatch(t1) 3 DERIVED t2 const PRIMARY PRIMARY 22 const 1 Using index -4 RECURSIVE UNION ALL NULL NULL NULL NULL 2 Using where -4 RECURSIVE UNION tt2 ref b1 b1 23 cte.a2 2 +4 RECURSIVE UNION tt2 ALL b1 NULL NULL NULL 14 Using where +4 RECURSIVE UNION ref key0 key0 23 test.tt2.b1 1 NULL UNION RESULT ALL NULL NULL NULL NULL NULL analyze format=json select fv from (select t1.a1, f1(t1.a2) fv from t1) dt @@ -3869,6 +3921,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -3876,9 +3929,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3895,9 +3950,11 @@ ANALYZE "key_length": "23", "used_key_parts": ["a2"], "ref": ["test.t1.a1"], + "loops": 3, "r_loops": 3, "rows": 1, "r_rows": 0.333333333, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3941,35 +3998,41 @@ ANALYZE "query_block": { "select_id": 4, "operation": "UNION", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ { "table": { - "table_name": "", + "table_name": "tt2", "access_type": "ALL", + "possible_keys": ["b1"], + "loops": 1, "r_loops": 1, - "rows": 2, - "r_rows": 1, + "rows": 14, + "r_rows": 14, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, "r_filtered": 100, - "attached_condition": "cte.a2 is not null" + "attached_condition": "tt2.b1 is not null" } }, { "table": { - "table_name": "tt2", + "table_name": "", "access_type": "ref", - "possible_keys": ["b1"], - "key": "b1", + "possible_keys": ["key0"], + "key": "key0", "key_length": "23", - "used_key_parts": ["b1"], - "ref": ["cte.a2"], - "r_loops": 1, - "rows": 2, - "r_rows": 1, + "used_key_parts": ["a2"], + "ref": ["test.tt2.b1"], + "loops": 14, + "r_loops": 14, + "rows": 1, + "r_rows": 0.071428571, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4032,8 +4095,8 @@ FROM cte JOIN t3 ON t3.tm BETWEEN cte.st AND cte.fn) SELECT t1.* FROM t1 JOIN cte2 USING (YEAR) JOIN cte3 USING (YEAR); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 -1 PRIMARY ref key0 key0 5 const 0 0.00 -1 PRIMARY ref key0 key0 5 const 0 0.00 +1 PRIMARY ref key0 key0 5 const 0 100.00 +1 PRIMARY ref key0 key0 5 const 0 100.00 2 DERIVED t1 system NULL NULL NULL NULL 1 100.00 3 RECURSIVE UNION t1 system NULL NULL NULL NULL 1 100.00 3 RECURSIVE UNION ALL NULL NULL NULL NULL 2 100.00 Using where @@ -4105,7 +4168,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 2 DERIVED s ALL NULL NULL NULL NULL 4 3 RECURSIVE UNION t1 ALL NULL NULL NULL NULL 4 Using where -3 RECURSIVE UNION ref key0 key0 9 test.t1.c 2 +3 RECURSIVE UNION ref key0 key0 9 test.t1.c 1 NULL UNION RESULT ALL NULL NULL NULL NULL NULL 4 UNION ALL NULL NULL NULL NULL 4 with recursive r_cte as @@ -4144,6 +4207,7 @@ ANALYZE "query_block": { "select_id": 4, "operation": "UNION", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -4151,9 +4215,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4169,6 +4235,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -4176,9 +4243,11 @@ ANALYZE "table": { "table_name": "s", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4192,6 +4261,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "UNION", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -4199,9 +4269,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4218,9 +4290,11 @@ ANALYZE "key_length": "9", "used_key_parts": ["a"], "ref": ["test.t1.c"], + "loops": 4, "r_loops": 4, - "rows": 2, + "rows": 1, "r_rows": 0.5, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4299,6 +4373,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -4306,9 +4381,11 @@ ANALYZE "table": { "table_name": "tt", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4467,9 +4544,9 @@ NULL UNION RESULT ALL NULL NULL NULL NULL NULL 3 DERIVED v ALL NULL NULL NULL NULL 12 Using where 3 DERIVED h ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 3 DERIVED w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join) -2 RECURSIVE UNION ALL NULL NULL NULL NULL 2 -2 RECURSIVE UNION h ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -2 RECURSIVE UNION w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join) +2 RECURSIVE UNION h ALL NULL NULL NULL NULL 12 Using where +2 RECURSIVE UNION ref key0 key0 5 test.h.id 1 +2 RECURSIVE UNION w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) NULL UNION RESULT ALL NULL NULL NULL NULL NULL prepare stmt from "with recursive ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, @@ -4565,9 +4642,9 @@ id select_type table type possible_keys key key_len ref rows Extra 4 RECURSIVE UNION ALL NULL NULL NULL NULL 2 5 RECURSIVE UNION ALL NULL NULL NULL NULL 2 NULL UNION RESULT ALL NULL NULL NULL NULL NULL -2 DERIVED h ALL NULL NULL NULL NULL 12 -2 DERIVED w ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join) -2 DERIVED ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join) +2 DERIVED h ALL NULL NULL NULL NULL 12 Using where +2 DERIVED ref key0 key0 5 test.h.id 1 +2 DERIVED w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) prepare stmt from "with recursive ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, w_id, w_name, w_dob, w_father, w_mother) diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test index 8efbdbf9677..06237c7b5dc 100644 --- a/mysql-test/main/cte_recursive.test +++ b/mysql-test/main/cte_recursive.test @@ -1110,6 +1110,7 @@ as ) select ancestors.name, ancestors.dob from ancestors; +--source include/explain-no-costs.inc explain FORMAT=JSON with recursive prev_gen @@ -1139,6 +1140,7 @@ as select ancestors.name, ancestors.dob from ancestors; --echo # +--source include/explain-no-costs.inc explain format=json with recursive ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, @@ -1343,6 +1345,7 @@ drop table folks; create table t1(a int); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +--source include/explain-no-costs.inc explain format=json with recursive t as (select a from t1 union select a+10 from t where a < 1000) select * from t; diff --git a/mysql-test/main/ctype_binary.result b/mysql-test/main/ctype_binary.result index 24fc961e17d..1dd5f93ad17 100644 --- a/mysql-test/main/ctype_binary.result +++ b/mysql-test/main/ctype_binary.result @@ -2763,6 +2763,7 @@ id INT(11) DEFAULT NULL, date_column DATE DEFAULT NULL, KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); +INSERT INTO t1 VALUES (3,'2012-09-01'),(4,'2012-10-01'),(5,'2012-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition diff --git a/mysql-test/main/ctype_collate.result b/mysql-test/main/ctype_collate.result index 1ae9f295042..29d27fd608b 100644 --- a/mysql-test/main/ctype_collate.result +++ b/mysql-test/main/ctype_collate.result @@ -748,7 +748,7 @@ hex(b) explain select hex(b) from t1 where b<'zzz' order by b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 34 NULL 4 Using where; Using filesort select hex(b) from t1 where b<'zzz' order by b; hex(b) 00 diff --git a/mysql-test/main/ctype_cp1251.result b/mysql-test/main/ctype_cp1251.result index a341d9ce471..475058dc2bb 100644 --- a/mysql-test/main/ctype_cp1251.result +++ b/mysql-test/main/ctype_cp1251.result @@ -3175,6 +3175,7 @@ id INT(11) DEFAULT NULL, date_column DATE DEFAULT NULL, KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); +INSERT INTO t1 VALUES (3,'2012-09-01'),(4,'2012-10-01'),(5,'2012-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition diff --git a/mysql-test/main/ctype_gbk.result b/mysql-test/main/ctype_gbk.result index 79dede6d089..9d7783b07bf 100644 --- a/mysql-test/main/ctype_gbk.result +++ b/mysql-test/main/ctype_gbk.result @@ -680,11 +680,7 @@ b MEDIUMTEXT CHARACTER SET big5); INSERT INTO t1 VALUES (REPEAT(0x1125,200000), REPEAT(0x1125,200000)), ('', ''), ('', ''); SELECT a FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT b FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll; -Warnings: -Warning 1287 ' INTO FROM...' instead DROP TABLES t1; End of 5.0 tests # diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index 5be12e91b68..4088530fc0f 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -3484,6 +3484,7 @@ id INT(11) DEFAULT NULL, date_column DATE DEFAULT NULL, KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); +INSERT INTO t1 VALUES (3,'2012-09-01'),(4,'2012-10-01'),(5,'2012-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition diff --git a/mysql-test/main/ctype_ucs.result b/mysql-test/main/ctype_ucs.result index ce0d695797b..987f1b704fd 100644 --- a/mysql-test/main/ctype_ucs.result +++ b/mysql-test/main/ctype_ucs.result @@ -207,8 +207,6 @@ DROP TABLE t1; # Problem # 1 (original report): wrong parsing of ucs2 data SET character_set_connection=ucs2; SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt'; -Warnings: -Warning 1287 ' INTO FROM...' instead CREATE TABLE t1(a INT); LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 (@b) SET a=REVERSE(@b); @@ -220,8 +218,6 @@ a DROP TABLE t1; # Problem # 2 : if you write and read ucs2 data to a file they're lost SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2; -Warnings: -Warning 1287 ' INTO FROM...' instead CREATE TABLE t1(a INT); LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2 (@b) SET a=REVERSE(@b); @@ -4368,6 +4364,7 @@ id INT(11) DEFAULT NULL, date_column DATE DEFAULT NULL, KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); +INSERT INTO t1 VALUES (3,'2012-09-01'),(4,'2012-10-01'),(5,'2012-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 5986ea3ac81..6d50a6cee2e 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -5235,6 +5235,7 @@ id INT(11) DEFAULT NULL, date_column DATE DEFAULT NULL, KEY(date_column)); INSERT INTO t1 VALUES (1,'2010-09-01'),(2,'2010-10-01'); +INSERT INTO t1 VALUES (3,'2012-09-01'),(4,'2012-10-01'),(5,'2012-10-01'); EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range date_column date_column 4 NULL 2 Using index condition diff --git a/mysql-test/main/custom_aggregates_i_s.result b/mysql-test/main/custom_aggregates_i_s.result index cb98aee389d..2a19e9f7cab 100644 --- a/mysql-test/main/custom_aggregates_i_s.result +++ b/mysql-test/main/custom_aggregates_i_s.result @@ -39,7 +39,7 @@ explain select * from t1, (select f1(sal) as a from t1 where id>= 1) q where q.a=t1.sal; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY ref key0 key0 5 test.t1.sal 2 +1 PRIMARY ref key0 key0 5 test.t1.sal 1 2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where show status like "%custom_aggregate%"; Variable_name Value diff --git a/mysql-test/main/delete.result b/mysql-test/main/delete.result index ed3683d52f9..830f60aa3c7 100644 --- a/mysql-test/main/delete.result +++ b/mysql-test/main/delete.result @@ -92,6 +92,9 @@ select * from t1; a b 1 apple drop table t1; +# +# IGNORE option +# create table t11 (a int NOT NULL, b int, primary key (a)); create table t12 (a int NOT NULL, b int, primary key (a)); create table t2 (a int NOT NULL, b int, primary key (a)); @@ -125,10 +128,14 @@ a b 33 10 0 11 2 12 +explain delete ignore t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b <> (select b from t2 where t11.a < t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t12 ALL PRIMARY NULL NULL NULL 3 +1 PRIMARY t11 eq_ref PRIMARY PRIMARY 4 test.t12.a 1 Using where +2 DEPENDENT SUBQUERY t2 ALL PRIMARY NULL NULL NULL 3 Using where delete ignore t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b <> (select b from t2 where t11.a < t2.a); Warnings: Warning 1242 Subquery returns more than 1 row -Warning 1242 Subquery returns more than 1 row select * from t11; a b 0 10 diff --git a/mysql-test/main/delete.test b/mysql-test/main/delete.test index c82420640c2..b95919ee4a4 100644 --- a/mysql-test/main/delete.test +++ b/mysql-test/main/delete.test @@ -106,9 +106,9 @@ delete t1 from t1, t1 as t2 where t1.b = t2.b and t1.a > t2.a; select * from t1; drop table t1; -# -# IGNORE option -# +--echo # +--echo # IGNORE option +--echo # create table t11 (a int NOT NULL, b int, primary key (a)); create table t12 (a int NOT NULL, b int, primary key (a)); create table t2 (a int NOT NULL, b int, primary key (a)); @@ -122,6 +122,7 @@ select * from t2; delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b <> (select b from t2 where t11.a < t2.a); select * from t11; select * from t12; +explain delete ignore t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b <> (select b from t2 where t11.a < t2.a); delete ignore t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b <> (select b from t2 where t11.a < t2.a); select * from t11; select * from t12; diff --git a/mysql-test/main/delete_innodb.result b/mysql-test/main/delete_innodb.result index b9f4c8bdaf5..ae9b415152f 100644 --- a/mysql-test/main/delete_innodb.result +++ b/mysql-test/main/delete_innodb.result @@ -17,7 +17,7 @@ a b EXPLAIN DELETE b FROM t1 AS a JOIN t1 AS b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE a index NULL PRIMARY 255 NULL 3 Using index +1 SIMPLE a ALL NULL NULL NULL NULL 3 1 SIMPLE b ALL NULL NULL NULL NULL 3 DELETE b FROM t1 AS a JOIN t1 AS b; SELECT * FROM t1; diff --git a/mysql-test/main/derived.result b/mysql-test/main/derived.result index 268b111cd77..91e85ef4339 100644 --- a/mysql-test/main/derived.result +++ b/mysql-test/main/derived.result @@ -370,6 +370,15 @@ a 2 3 3 +set @save2_derived_optimizer_switch_bug=@@optimizer_switch; +set @@optimizer_switch=default; +select * from (select * from t1 union distinct select * from t2 union all select * from t3) X; +a +1 +2 +3 +3 +set @@optimizer_switch=@save2_derived_optimizer_switch_bug; drop table t1, t2, t3; create table t1 (a int); create table t2 (a int); @@ -1283,14 +1292,14 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f analyze select * from t1 , ((select distinct t2.a, t2.b from t2 order by c))q where t1.a=q.a; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 1.00 100.00 100.00 +1 PRIMARY ref key0 key0 5 test.t1.a 1 1.00 100.00 100.00 2 DERIVED t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using temporary; Using filesort # multiple selects in derived table # NO UNION ALL analyze select * from t1 , ( (select t2.a from t2 order by c) union (select t2.a from t2 order by c))q where t1.a=q.a; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 1 1.00 100.00 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 1.00 100.00 100.00 2 DERIVED t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 3 UNION t2 ALL NULL NULL NULL NULL 6 6.00 100.00 100.00 NULL UNION RESULT ALL NULL NULL NULL NULL NULL 6.00 NULL NULL @@ -1333,3 +1342,101 @@ DROP TABLE t1; # # End of 10.3 tests # +# +# Test of "Derived tables and union can now create distinct keys" +# +create table t1 (a int); +insert into t1 values (100),(100),(100),(100),(100),(100),(100),(100),(100),(100); +create table duplicates_tbl (a int); +insert into duplicates_tbl select seq/100 from seq_1_to_10000; +explain +select +t1.a IN ( SELECT COUNT(*) +from (select a +from duplicates_tbl +limit 10000 +) T +where T.a=5 +) as 'A' +from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED ALL NULL NULL NULL NULL 10000 Using where +3 DERIVED duplicates_tbl ALL NULL NULL NULL NULL 10000 +select +t1.a IN ( SELECT COUNT(*) +from (select a +from duplicates_tbl +limit 10000 +) T +where T.a=5 +) as 'A' +from t1; +A +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +explain +select +t1.a = all ( SELECT COUNT(*) +from (select a +from duplicates_tbl +limit 10000 +) T +where T.a=5 +) as 'A' +from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 DEPENDENT SUBQUERY ALL NULL NULL NULL NULL 10000 Using where +3 DERIVED duplicates_tbl ALL NULL NULL NULL NULL 10000 +select +t1.a = all ( SELECT COUNT(*) +from (select a +from duplicates_tbl +limit 10000 +) T +where T.a=5 +) as 'A' +from t1; +A +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +drop table t1, duplicates_tbl; +# +# MDEV-30310 +# Assertion failure in best_access_path upon IN exceeding +# IN_PREDICATE_CONVERSION_THRESHOLD, derived_with_keys=off +# +CREATE TABLE t1 (l_orderkey int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (o_orderkey int); +INSERT INTO t2 VALUES (3),(4); +SET IN_PREDICATE_CONVERSION_THRESHOLD= 2; +SET OPTIMIZER_SWITCH='derived_with_keys=on'; +SELECT * FROM t1 JOIN t2 ON (l_orderkey = o_orderkey) WHERE l_orderkey IN (1, 2, 3); +l_orderkey o_orderkey +SET OPTIMIZER_SWITCH='derived_with_keys=off'; +SELECT * FROM t1 JOIN t2 ON (l_orderkey = o_orderkey) WHERE l_orderkey IN (1, 2, 3); +l_orderkey o_orderkey +SET @@IN_PREDICATE_CONVERSION_THRESHOLD=@@global.IN_PREDICATE_CONVERSION_THRESHOLD; +SET @@OPTIMIZER_SWITCH=@@global.OPTIMIZER_SWITCH; +DROP TABLE t1, t2; +# +# End of 11.0 tests +# diff --git a/mysql-test/main/derived.test b/mysql-test/main/derived.test index b256637ce26..5119bca4ea8 100644 --- a/mysql-test/main/derived.test +++ b/mysql-test/main/derived.test @@ -260,6 +260,10 @@ insert into t2 values(2),(2); insert into t3 values(3),(3); select * from t1 union distinct select * from t2 union all select * from t3; select * from (select * from t1 union distinct select * from t2 union all select * from t3) X; +set @save2_derived_optimizer_switch_bug=@@optimizer_switch; +set @@optimizer_switch=default; +select * from (select * from t1 union distinct select * from t2 union all select * from t3) X; +set @@optimizer_switch=@save2_derived_optimizer_switch_bug; drop table t1, t2, t3; # @@ -1128,7 +1132,6 @@ select * from t1 , ( (select t2.a from t2 order by c) union all (select t2.a fr drop table t1,t2,t3; - --echo # --echo # MDEV-16549: Server crashes in Item_field::fix_fields on query with --echo # view and subquery, Assertion `context' failed, Assertion `field' failed @@ -1147,3 +1150,80 @@ DROP TABLE t1; --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # Test of "Derived tables and union can now create distinct keys" +--echo # + +create table t1 (a int); +insert into t1 values (100),(100),(100),(100),(100),(100),(100),(100),(100),(100); + +create table duplicates_tbl (a int); +insert into duplicates_tbl select seq/100 from seq_1_to_10000; + +explain +select + t1.a IN ( SELECT COUNT(*) + from (select a + from duplicates_tbl + limit 10000 + ) T + where T.a=5 + ) as 'A' +from t1; + +select + t1.a IN ( SELECT COUNT(*) + from (select a + from duplicates_tbl + limit 10000 + ) T + where T.a=5 + ) as 'A' +from t1; + +explain +select + t1.a = all ( SELECT COUNT(*) + from (select a + from duplicates_tbl + limit 10000 + ) T + where T.a=5 + ) as 'A' +from t1; + +select + t1.a = all ( SELECT COUNT(*) + from (select a + from duplicates_tbl + limit 10000 + ) T + where T.a=5 + ) as 'A' +from t1; + +drop table t1, duplicates_tbl; + +--echo # +--echo # MDEV-30310 +--echo # Assertion failure in best_access_path upon IN exceeding +--echo # IN_PREDICATE_CONVERSION_THRESHOLD, derived_with_keys=off +--echo # + +CREATE TABLE t1 (l_orderkey int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (o_orderkey int); +INSERT INTO t2 VALUES (3),(4); +SET IN_PREDICATE_CONVERSION_THRESHOLD= 2; +SET OPTIMIZER_SWITCH='derived_with_keys=on'; +SELECT * FROM t1 JOIN t2 ON (l_orderkey = o_orderkey) WHERE l_orderkey IN (1, 2, 3); +SET OPTIMIZER_SWITCH='derived_with_keys=off'; +SELECT * FROM t1 JOIN t2 ON (l_orderkey = o_orderkey) WHERE l_orderkey IN (1, 2, 3); +SET @@IN_PREDICATE_CONVERSION_THRESHOLD=@@global.IN_PREDICATE_CONVERSION_THRESHOLD; +SET @@OPTIMIZER_SWITCH=@@global.OPTIMIZER_SWITCH; +DROP TABLE t1, t2; + +--echo # +--echo # End of 11.0 tests +--echo # diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index e07f2550297..acc52daed43 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -122,12 +122,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -136,7 +139,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 214" }, @@ -147,6 +152,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 214", "filesort": { "sort_key": "t1.a, t1.b", @@ -156,7 +162,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -208,12 +216,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -227,12 +238,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 300", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -242,7 +256,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -297,12 +313,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -311,7 +330,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 400 or v1.max_c < 135" }, @@ -322,6 +343,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (max_c > 400 or max_c < 135)", "filesort": { "sort_key": "t1.a, t1.b", @@ -331,7 +353,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -375,12 +399,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -389,7 +416,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 300 or v1.max_c < 135" }, @@ -400,6 +429,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (max_c > 300 or max_c < 135)", "filesort": { "sort_key": "t1.a, t1.b", @@ -409,7 +439,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -442,12 +474,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -456,7 +491,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 6" }, @@ -467,6 +504,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -476,7 +514,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 6" } @@ -519,12 +559,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -533,7 +576,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.b > 25" }, @@ -544,6 +589,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -553,7 +599,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and t1.b > 25" } @@ -617,12 +665,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -631,7 +682,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 7 or v1.a < 2" }, @@ -642,6 +695,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -651,7 +705,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 7 or t1.a < 2" } @@ -708,12 +764,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -722,7 +781,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.a > 7 or v2.a > 5" }, @@ -733,6 +794,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -742,7 +804,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and (t1.a > 7 or t1.a > 5)" } @@ -785,12 +849,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -799,7 +866,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 4 or v1.a < 2" }, @@ -810,6 +879,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -819,7 +889,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 4 or t1.a < 2" } @@ -855,12 +927,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -869,7 +944,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 2 and v1.max_c > 400" }, @@ -880,6 +957,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 400", "filesort": { "sort_key": "t1.a, t1.b", @@ -889,7 +967,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2" } @@ -928,7 +1008,7 @@ explain select * from v_double as v,t2_double as t where (v.a=t.a) and (v.avg_a>0.45) and (v.b>10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t.a 1 Using where 2 DERIVED t1_double ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort explain format=json select * from v_double as v,t2_double as t where (v.a=t.a) and (v.avg_a>0.45) and (v.b>10); @@ -936,12 +1016,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a is not null" } @@ -955,12 +1038,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.avg_a > 0.45 and v.b > 10", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "avg_a < 22.333 and avg_a > 0.45", "filesort": { "sort_key": "t1_double.b, t1_double.c", @@ -970,7 +1056,9 @@ EXPLAIN "table": { "table_name": "t1_double", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_double.b > 12.2 and t1_double.b > 10" } @@ -997,7 +1085,7 @@ explain select * from v_decimal as v,t2_decimal as t where (v.a=t.a) and (v.avg_c>15) and (v.b>1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 3 test.t.a 2 Using where +1 PRIMARY ref key0 key0 3 test.t.a 1 Using where 2 DERIVED t1_decimal ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort explain format=json select * from v_decimal as v,t2_decimal as t where (v.a=t.a) and (v.avg_c>15) and (v.b>1); @@ -1005,12 +1093,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a is not null" } @@ -1024,12 +1115,15 @@ EXPLAIN "key_length": "3", "used_key_parts": ["a"], "ref": ["test.t.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.avg_c > 15 and v.b > 1", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "avg_c > 12 and avg_c > 15", "filesort": { "sort_key": "t1_decimal.a, t1_decimal.b", @@ -1039,7 +1133,9 @@ EXPLAIN "table": { "table_name": "t1_decimal", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_decimal.b > 1" } @@ -1097,12 +1193,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1111,7 +1210,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 7 and v1.max_c > 300 or v1.a < 4 and v1.max_c < 500" }, @@ -1122,6 +1223,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (t1.a > 7 and max_c > 300 or t1.a < 4 and max_c < 500)", "filesort": { "sort_key": "t1.a, t1.b", @@ -1131,7 +1233,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 7 or t1.a < 4" } @@ -1196,12 +1300,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1210,7 +1317,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 2 and v1.max_c > 120 or v1.a > 7" }, @@ -1221,6 +1330,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (t1.a < 2 and max_c > 120 or t1.a > 7)", "filesort": { "sort_key": "t1.a, t1.b", @@ -1230,7 +1340,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2 or t1.a > 7" } @@ -1284,12 +1396,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1298,7 +1413,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 2 and v1.max_c > 120 or v1.a > 7" }, @@ -1309,6 +1426,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (t1.a < 2 and max_c > 120 or t1.a > 7)", "filesort": { "sort_key": "t1.a, t1.b", @@ -1318,7 +1436,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2 or t1.a > 7" } @@ -1361,12 +1481,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1375,7 +1498,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 2 and v1.max_c < 200 or v1.a > 4" }, @@ -1386,6 +1511,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (t1.a < 2 and max_c < 200 or t1.a > 4 and max_c < 500)", "filesort": { "sort_key": "t1.a, t1.b", @@ -1395,7 +1521,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2 or t1.a > 4" } @@ -1448,12 +1576,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1462,7 +1593,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 400 or v1.max_c < 135" }, @@ -1473,6 +1606,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (max_c > 400 or max_c < 135)", "filesort": { "sort_key": "t1.a, t1.b", @@ -1482,7 +1616,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1501,12 +1637,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1515,7 +1654,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 400 or v1.max_c < 135" }, @@ -1526,6 +1667,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (max_c > 400 or max_c < 135)", "filesort": { "sort_key": "t1.a, t1.b", @@ -1535,7 +1677,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1570,12 +1714,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 1 and t2.b is not null" } @@ -1589,12 +1736,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t2.b"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 1", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.b", @@ -1604,7 +1754,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -1635,12 +1787,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.d is not null" } @@ -1654,12 +1809,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["max_c"], "ref": ["test.t2.d"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 5 and v1.max_c = t2.d", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.b", @@ -1669,7 +1827,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 5" } @@ -1707,12 +1867,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 5 and t2.a is not null" } @@ -1726,11 +1889,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -1740,7 +1906,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 5" } @@ -1769,12 +1937,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null and t2.a is not null" } @@ -1788,11 +1959,14 @@ EXPLAIN "key_length": "10", "used_key_parts": ["a", "b"], "ref": ["test.t2.a", "test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -1802,7 +1976,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t1.a" } @@ -1836,12 +2012,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.c > 150 and t2.c is not null" } @@ -1855,11 +2034,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["max_c"], "ref": ["test.t2.c"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 150", "filesort": { "sort_key": "t1.a, t1.b", @@ -1869,7 +2051,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1899,12 +2083,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 3" } @@ -1914,7 +2101,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 3 and v1.b = 3" }, @@ -1924,13 +2113,16 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 3 and t1.b = 3" } @@ -1959,12 +2151,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 2" } @@ -1974,7 +2169,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 1 and v1.b = 21" }, @@ -1984,13 +2181,16 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.b = 21" } @@ -2025,17 +2225,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.a = 'c' and v.b < 'Hermes'", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 9", "filesort": { "sort_key": "t1_char.b", @@ -2045,7 +2249,9 @@ EXPLAIN "table": { "table_name": "t1_char", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_char.a = 'c' and t1_char.b < 'Hermes'" } @@ -2062,7 +2268,9 @@ EXPLAIN "table": { "table_name": "t", "access_type": "ALL", + "loops": 12, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -2100,7 +2308,7 @@ explain select * from v_decimal as v,t2_decimal as t where (v.a=v.b) and (v.b=t.b) and ((t.b>1) or (v.a=1)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 6 test.t.b,test.t.b 2 +1 PRIMARY ref key0 key0 6 test.t.b,test.t.b 1 2 DERIVED t1_decimal ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort explain format=json select * from v_decimal as v,t2_decimal as t where (v.a=v.b) and (v.b=t.b) and ((t.b>1) or (v.a=1)); @@ -2108,12 +2316,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t.b > 1 or t.b = 1) and t.b is not null and t.b is not null" } @@ -2127,11 +2338,14 @@ EXPLAIN "key_length": "6", "used_key_parts": ["a", "b"], "ref": ["test.t.b", "test.t.b"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "avg_c > 12", "filesort": { "sort_key": "t1_decimal.a, t1_decimal.b", @@ -2141,7 +2355,9 @@ EXPLAIN "table": { "table_name": "t1_decimal", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_decimal.b = t1_decimal.a and (t1_decimal.a > 1 or t1_decimal.a = 1)" } @@ -2187,12 +2403,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 4 or t2.c > 150" } @@ -2202,7 +2421,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -2212,6 +2433,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (t1.a < 4 or max_c > 150)", "filesort": { "sort_key": "t1.a, t1.b", @@ -2221,7 +2443,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2256,12 +2480,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 5 and t2.c > 250 and t2.a is not null and t2.c is not null" } @@ -2275,11 +2502,14 @@ EXPLAIN "key_length": "10", "used_key_parts": ["a", "max_c"], "ref": ["test.t2.a", "test.t2.c"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 250", "filesort": { "sort_key": "t1.a, t1.b", @@ -2289,7 +2519,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -2336,12 +2568,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 8" } @@ -2351,7 +2586,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 8 and v1.max_c = 404" }, @@ -2361,6 +2598,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c = 404", "filesort": { "sort_key": "t1.b", @@ -2370,7 +2608,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 8" } @@ -2406,12 +2646,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.d is not null" } @@ -2425,12 +2668,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["max_c"], "ref": ["test.t2.d"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 3 and v1.max_c > 200 and t2.b < v1.b and t2.d = v1.max_c", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -2440,7 +2686,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 3" } @@ -2468,7 +2716,7 @@ explain select * from v_double as v,t2_double as t where (v.b=v.c) and (v.c=t.c) and ((t.c>10) or (v.a=1)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 18 test.t.c,test.t.c 2 Using where +1 PRIMARY ref key0 key0 18 test.t.c,test.t.c 1 Using where 2 DERIVED t1_double ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort explain format=json select * from v_double as v,t2_double as t where (v.b=v.c) and (v.c=t.c) and ((t.c>10) or (v.a=1)); @@ -2476,12 +2724,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.c is not null and t.c is not null" } @@ -2495,12 +2746,15 @@ EXPLAIN "key_length": "18", "used_key_parts": ["b", "c"], "ref": ["test.t.c", "test.t.c"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.c > 10 or v.a = 1", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "avg_a < 22.333 and (t1_double.b > 10 or t1_double.a = 1)", "filesort": { "sort_key": "t1_double.b, t1_double.c", @@ -2510,7 +2764,9 @@ EXPLAIN "table": { "table_name": "t1_double", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_double.c = t1_double.b and t1_double.b > 12.2" } @@ -2543,7 +2799,7 @@ explain select * from v_double as v,t2_double as t where (((v.a>0.2) or (v.b<17)) or (t.c>17)) and (t.c=v.c) and (v.c>18); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 9 test.t.c 2 Using where +1 PRIMARY ref key0 key0 9 test.t.c 1 Using where 2 DERIVED t1_double ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort explain format=json select * from v_double as v,t2_double as t where (((v.a>0.2) or (v.b<17)) or (t.c>17)) and (t.c=v.c) and (v.c>18); @@ -2551,12 +2807,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.c > 18 and t.c is not null" } @@ -2570,12 +2829,15 @@ EXPLAIN "key_length": "9", "used_key_parts": ["c"], "ref": ["test.t.c"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.a > 0.2 or v.b < 17 or t.c > 17", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "avg_a < 22.333 and (t1_double.a > 0.2 or t1_double.b < 17 or t1_double.c > 17)", "filesort": { "sort_key": "t1_double.b, t1_double.c", @@ -2585,7 +2847,9 @@ EXPLAIN "table": { "table_name": "t1_double", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_double.b > 12.2 and t1_double.c > 18" } @@ -2657,17 +2921,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(v.a > 4 or v.a = 2 or v.b > 3) and v.avg_c = 13", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "avg_c > 12 and avg_c = 13", "filesort": { "sort_key": "t1_decimal.a, t1_decimal.b", @@ -2677,7 +2945,9 @@ EXPLAIN "table": { "table_name": "t1_decimal", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_decimal.a > 4 or t1_decimal.a = 2 or t1_decimal.b > 3" } @@ -2694,7 +2964,9 @@ EXPLAIN "table": { "table_name": "t", "access_type": "ALL", + "loops": 9, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -2731,12 +3003,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null and t2.a is not null" } @@ -2750,12 +3025,15 @@ EXPLAIN "key_length": "10", "used_key_parts": ["a", "b"], "ref": ["test.t2.a", "test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 300", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -2765,7 +3043,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t1.a and t1.a > 5" } @@ -2807,12 +3087,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 2 and t2.c > 900" } @@ -2822,7 +3105,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -2831,6 +3116,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -2840,7 +3126,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2874,12 +3162,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null and t2.b is not null" } @@ -2893,11 +3184,14 @@ EXPLAIN "key_length": "10", "used_key_parts": ["a", "b"], "ref": ["test.t2.a", "test.t2.b"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -2907,7 +3201,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2955,12 +3251,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -2969,7 +3268,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -2979,6 +3280,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -2988,7 +3290,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3060,12 +3364,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -3074,7 +3381,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -3084,6 +3393,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3093,7 +3403,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3137,12 +3449,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 2 and t2.c > 900" } @@ -3152,7 +3467,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -3162,6 +3479,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3171,7 +3489,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3214,12 +3534,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null and t2.a is not null" } @@ -3233,11 +3556,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3247,7 +3573,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3267,12 +3595,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 18, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.b < 50", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3282,7 +3613,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and t1.b < 50" } @@ -3345,12 +3678,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b < 50" } @@ -3360,7 +3696,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -3370,6 +3708,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3379,7 +3718,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3399,12 +3740,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["v1.b"], + "loops": 180, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.a = v1.a or v1.a = t2.a", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3414,7 +3758,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -3457,12 +3803,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -3471,7 +3820,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -3481,6 +3832,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3490,7 +3842,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3506,7 +3860,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 180, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "incremental", @@ -3516,6 +3872,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3525,7 +3882,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -3572,12 +3931,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -3586,7 +3948,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c < 300" }, @@ -3596,6 +3960,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c < 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -3605,7 +3970,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3621,7 +3988,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 180, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.b < 50 or v2.b = 19" }, @@ -3632,6 +4001,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3641,7 +4011,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and (t1.b < 50 or t1.b = 19)" } @@ -3679,12 +4051,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null and t2.a is not null and t2.a is not null" } @@ -3698,11 +4073,14 @@ EXPLAIN "key_length": "10", "used_key_parts": ["a", "b"], "ref": ["test.t2.a", "test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3712,7 +4090,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t1.a" } @@ -3733,12 +4113,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 18, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.max_c < 300", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c < 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -3748,7 +4131,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -3783,12 +4168,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -3797,7 +4185,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 1 and v1.b > 10" }, @@ -3808,6 +4198,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.b", @@ -3817,7 +4208,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.b > 10" } @@ -3838,11 +4231,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["v1.b"], + "loops": 180, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -3852,7 +4248,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and t1.b > 10" } @@ -3898,17 +4296,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.a = 'b' and (v.b = 'Vika' or v.b = 'Ali')", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 9", "filesort": { "sort_key": "t1_char.b", @@ -3918,7 +4320,9 @@ EXPLAIN "table": { "table_name": "t1_char", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_char.a = 'b' and (t1_char.b = 'Vika' or t1_char.b = 'Ali')" } @@ -3935,7 +4339,9 @@ EXPLAIN "table": { "table_name": "t", "access_type": "ALL", + "loops": 12, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a = 'b'" }, @@ -4005,12 +4411,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -4024,12 +4433,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v3.b < 50 or v3.b = 33", "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "min_c > 109", "filesort": { "sort_key": "t1.a, t1.b", @@ -4039,7 +4451,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and (t1.b < 50 or t1.b = 33)" } @@ -4056,7 +4470,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 18, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c < 500" }, @@ -4066,6 +4482,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c < 500", "filesort": { "sort_key": "t1.a, t1.b", @@ -4075,7 +4492,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -4091,7 +4510,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 360, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.max_c > 300" }, @@ -4102,6 +4523,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -4111,7 +4533,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -4164,12 +4588,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b is not null" } @@ -4183,12 +4610,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t2.b"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 130 and v1.a is not null", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -4198,7 +4628,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -4219,12 +4651,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["v1.a"], + "loops": 18, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.min_c < 130", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "min_c < 707 and min_c < 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -4234,7 +4669,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -4320,12 +4757,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -4334,7 +4774,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.avg_c < 400 or v1.a > 1" }, @@ -4345,6 +4787,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (avg_c < 400 or t1.a > 1)", "filesort": { "sort_key": "t1.a, t1.b", @@ -4354,7 +4797,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -4375,12 +4820,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["v1.a"], + "loops": 180, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.min_c < 200", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "min_c < 707 and min_c < 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -4390,7 +4838,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -4411,12 +4861,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["v1.b"], + "loops": 360, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v3.avg_c > 170 or v3.a < 5", "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "avg_c > 170 or t1.a < 5", "filesort": { "sort_key": "t1.a, t1.b", @@ -4426,7 +4879,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 8" } @@ -4487,12 +4942,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -4501,7 +4959,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(v1.a = 1 or v1.max_c < 300) and v1.b > 25" }, @@ -4512,6 +4972,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (t1.a = 1 or max_c < 300)", "filesort": { "sort_key": "t1.a, t1.b", @@ -4521,7 +4982,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 25" } @@ -4568,12 +5031,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -4587,12 +5053,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 300 and v1.b < 30", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -4602,7 +5071,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and t1.b < 30" } @@ -4656,12 +5127,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.c > 800 and t2.b is not null" } @@ -4675,12 +5149,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t2.b"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 5", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -4690,7 +5167,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 5" } @@ -4709,12 +5188,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.d > 800" } @@ -4724,7 +5206,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 100 and v1.a > 7" }, @@ -4734,6 +5218,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 100", "filesort": { "sort_key": "t1.a, t1.b", @@ -4743,7 +5228,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 7" } @@ -4820,12 +5307,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b = 19" } @@ -4835,7 +5325,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b = 19 and v1.a < 5" }, @@ -4845,6 +5337,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a", @@ -4854,7 +5347,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 19 and t1.a < 5" } @@ -4873,12 +5368,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -4887,7 +5385,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 400 or v1.avg_c > 270" }, @@ -4898,6 +5398,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (max_c > 400 or avg_c > 270)", "filesort": { "sort_key": "t1.a, t1.b", @@ -4907,7 +5408,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -4995,12 +5498,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -5009,7 +5515,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 1 or v1.a = 6" }, @@ -5020,6 +5528,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -5029,7 +5538,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 or t1.a = 6" } @@ -5048,12 +5559,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -5062,7 +5576,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 3 and v1.b > 27 or v1.max_c > 550" }, @@ -5073,6 +5589,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (t1.a > 3 and t1.b > 27 or max_c > 550)", "filesort": { "sort_key": "t1.a, t1.b", @@ -5082,7 +5599,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -5171,12 +5690,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 1" } @@ -5186,7 +5708,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 1 and (v1.max_c < 500 or v1.avg_c > 500)" }, @@ -5197,6 +5721,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and (max_c < 500 or avg_c > 500)", "filesort": { "sort_key": "t1.b", @@ -5206,7 +5731,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -5225,12 +5752,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 2" } @@ -5240,7 +5770,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.b > 10" }, @@ -5251,6 +5783,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 5, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -5260,7 +5793,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and t1.b > 10" } @@ -5279,12 +5814,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.c is not null" } @@ -5298,12 +5836,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["max_c"], "ref": ["test.t2.c"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.b < 10", "materialized": { "query_block": { "select_id": 6, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -5313,7 +5854,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and t1.b < 10" } @@ -5368,12 +5911,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -5382,7 +5928,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 40, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v_union.a < 3 and v_union.c > 100" }, @@ -5398,6 +5946,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 109 and c > 100", "filesort": { "sort_key": "t1.a, t1.b", @@ -5407,7 +5956,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and t1.a < 3" } @@ -5421,6 +5972,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 300 and c > 100", "filesort": { "sort_key": "t1.a, t1.b", @@ -5430,7 +5982,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a < 3" } @@ -5490,12 +6044,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -5504,7 +6061,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 40, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(v_union.a < 2 or v_union.c > 800) and v_union.b > 12" }, @@ -5521,6 +6080,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 109 and (t1.a < 2 or c > 800)", "filesort": { "sort_key": "t1.a, t1.b", @@ -5530,7 +6090,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and t1.b > 12" } @@ -5544,6 +6106,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 300 and (t1.a < 2 or c > 800)", "filesort": { "sort_key": "t1.a, t1.b", @@ -5553,7 +6116,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.b > 12" } @@ -5600,12 +6165,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 1" } @@ -5615,7 +6183,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 40, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v_union.a = 1 and v_union.c < 200" }, @@ -5631,6 +6201,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 109 and c < 200", "filesort": { "sort_key": "t1.b", @@ -5640,7 +6211,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -5654,6 +6227,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 300 and c < 200", "filesort": { "sort_key": "t1.b", @@ -5663,7 +6237,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.b > 10" } @@ -5700,7 +6276,7 @@ explain select * from v_char as v,t2_char as t where (v.a=t.a) and (v.b='Vika') and (v.max_c>2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL NULL NULL NULL NULL 12 Using where -1 PRIMARY ref key0 key0 2 test.t.a 2 Using where +1 PRIMARY ref key0 key0 2 test.t.a 1 Using where 2 DERIVED t1_char ALL NULL NULL NULL NULL 12 Using where; Using temporary; Using filesort explain format=json select * from v_char as v,t2_char as t where (v.a=t.a) and (v.b='Vika') and (v.max_c>2); @@ -5708,12 +6284,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a is not null" } @@ -5727,12 +6306,15 @@ EXPLAIN "key_length": "2", "used_key_parts": ["a"], "ref": ["test.t.a"], - "rows": 2, + "loops": 12, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.b = 'Vika' and v.max_c > 2", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 9 and max_c > 2", "filesort": { "sort_key": "t1_char.a", @@ -5742,7 +6324,9 @@ EXPLAIN "table": { "table_name": "t1_char", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1_char.b = 'Vika'" } @@ -5791,12 +6375,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 1" } @@ -5806,7 +6393,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 1" }, @@ -5816,6 +6405,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.b", @@ -5825,7 +6415,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -5842,7 +6434,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 180, "rows": 40, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v_union.a = 1" }, @@ -5859,6 +6453,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 109", "filesort": { "sort_key": "t1.b", @@ -5868,7 +6463,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -5882,6 +6479,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.b", @@ -5891,7 +6489,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.b > 10" } @@ -5947,12 +6547,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t2.a = 6 or t2.a = 8) and t2.a is not null" } @@ -5966,7 +6569,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 6, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.c > 200", "materialized": { @@ -5978,6 +6583,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 109 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -5987,7 +6593,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and (t1.a = 6 or t1.a = 8)" } @@ -6001,6 +6609,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 300 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -6010,7 +6619,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and (t1.a = 6 or t1.a = 8)" } @@ -6024,6 +6635,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 707 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -6033,7 +6645,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c > 300 and (t1.a = 6 or t1.a = 8)" } @@ -6134,12 +6748,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -6153,7 +6770,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.c > 6", "materialized": { @@ -6165,12 +6784,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and t1.a + 1 > 6" } @@ -6182,12 +6804,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.c > 100 and t1.c > 6" } @@ -6266,12 +6891,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -6285,7 +6913,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 1 or v.b < 20", "materialized": { @@ -6297,12 +6927,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and (t1.a > 1 or t1.b < 20)" } @@ -6314,12 +6947,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.c > 100 and (t1.a > 1 or t1.b < 20)" } @@ -6366,12 +7002,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -6385,7 +7024,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(v.b = 19 or v.b = 21) and (v.c < 3 or v.c > 600)", "materialized": { @@ -6397,12 +7038,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and (t1.b = 19 or t1.b = 21) and (t1.a + 1 < 3 or t1.a + 1 > 600)" } @@ -6414,12 +7058,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.c > 100 and (t1.b = 19 or t1.b = 21) and (t1.c < 3 or t1.c > 600)" } @@ -6463,12 +7110,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -6482,7 +7132,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v.b < 20", "materialized": { @@ -6494,6 +7146,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 109", "filesort": { "sort_key": "t1.a, t1.b", @@ -6503,7 +7156,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and t1.b < 20" } @@ -6517,12 +7172,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.b < 20" } @@ -6585,12 +7243,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -6604,7 +7265,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t2.a < 3 or v.b < 40) and v.c > 500", "materialized": { @@ -6616,6 +7279,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 109 and c > 500", "filesort": { "sort_key": "t1.a, t1.b", @@ -6625,7 +7289,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 10 and (t1.a < 3 or t1.b < 40)" } @@ -6639,12 +7305,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and (t1.a < 3 or t1.b < 40) and t1.c + 100 > 500" } @@ -6709,17 +7378,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v4.a < 13", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.a, v1.b", "temporary_table": { @@ -6728,12 +7401,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 15 and v1.a < 13", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -6743,7 +7419,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 15 and t1.a < 13" } @@ -6767,7 +7445,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 20, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 5 and v1.b > 12" }, @@ -6777,6 +7457,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -6786,7 +7467,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and t1.b > 12" } @@ -6829,12 +7512,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null and t2.a is not null" } @@ -6848,11 +7534,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.a, v1.b", "temporary_table": { @@ -6861,12 +7550,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 15", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -6876,7 +7568,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 15" } @@ -6904,12 +7598,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 18, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b > 30", "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -6919,7 +7616,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 30" } @@ -6964,12 +7663,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 1 and t2.a is not null and t2.a is not null" } @@ -6983,12 +7685,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v4.min_c > 100", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "min_c > 100", "filesort": { "sort_key": "v1.a, v1.b", @@ -6998,12 +7703,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 15 and v1.a > 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7013,7 +7721,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 15 and t1.a > 1" } @@ -7041,12 +7751,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 18, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b < 30", "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7056,7 +7769,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.b < 30" } @@ -7186,12 +7901,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -7200,7 +7918,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v4.b > 10 and v4.a > 1 or v4.b < 20" }, @@ -7211,6 +7931,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.a, v1.b", "temporary_table": { @@ -7219,12 +7940,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 15 and (v1.b > 10 and v1.a > 1 or v1.b < 20)", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7234,7 +7958,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 15 and (t1.b > 10 and t1.a > 1 or t1.b < 20)" } @@ -7262,12 +7988,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["v4.a"], + "loops": 180, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 200", "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -7277,7 +8006,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -7315,17 +8046,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v4.a > 12 and v4.min_c < 300 and v4.b > 13 or v4.a < 1", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "v1.a > 12 and min_c < 300 and v1.b > 13 or v1.a < 1", "filesort": { "sort_key": "v1.a, v1.b", @@ -7335,12 +8070,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 15 and (v1.a > 12 and v1.b > 13 or v1.a < 1)", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7350,7 +8088,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 15 and (t1.a > 12 and t1.b > 13 or t1.a < 1)" } @@ -7374,7 +8114,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 20, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -7383,6 +8125,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7392,7 +8135,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -7432,17 +8177,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v4.b = v4.a and v4.min_c < 100 and v4.a is not null", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "min_c < 100", "filesort": { "sort_key": "v1.a, v1.b", @@ -7452,12 +8201,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b = v1.a and v1.a < 15", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7467,7 +8219,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t1.a and t1.a < 15" } @@ -7495,11 +8249,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["v4.a"], + "loops": 20, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7509,7 +8266,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -7549,17 +8308,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v4.b = v4.a and v4.a < 30 and v4.a is not null", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.a, v1.b", "temporary_table": { @@ -7568,12 +8331,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b = v1.a and v1.a < 15 and v1.a < 30", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7583,7 +8349,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t1.a and t1.a < 15 and t1.a < 30" } @@ -7611,11 +8379,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["v4.a"], + "loops": 20, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7625,7 +8396,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and t1.b < 30" } @@ -7665,17 +8438,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v4.b = v4.a and (v4.a < 30 or v4.a > 2) and v4.a is not null", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.a, v1.b", "temporary_table": { @@ -7684,12 +8461,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b = v1.a and v1.a < 15 and (v1.a < 30 or v1.a > 2)", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7699,7 +8479,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t1.a and t1.a < 15 and (t1.a < 30 or t1.a > 2)" } @@ -7727,11 +8509,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["v4.a"], + "loops": 20, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7741,7 +8526,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5 and (t1.b < 30 or t1.b > 2)" } @@ -7789,17 +8576,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(v4.a < 12 and v4.b > 13 or v4.a > 10) and v4.min_c > 100 and v4.min_c is not null", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "min_c > 100", "filesort": { "sort_key": "v1.a, v1.b", @@ -7809,12 +8600,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 15 and (v1.a < 12 and v1.b > 13 or v1.a > 10)", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7824,7 +8618,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 15 and (t1.a < 12 and t1.b > 13 or t1.a > 10)" } @@ -7852,11 +8648,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["max_c"], "ref": ["v4.min_c"], + "loops": 20, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707 and max_c > 100", "filesort": { "sort_key": "t1.a, t1.b", @@ -7866,7 +8665,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -7913,12 +8714,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.c > 100 and t2.c is not null" } @@ -7932,12 +8736,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["min_c"], "ref": ["test.t2.c"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v4.a < 12 and t2.b > 13 or v4.a > 10", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "min_c > 100", "filesort": { "sort_key": "v1.a, v1.b", @@ -7947,12 +8754,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 15 and (v1.a < 12 or v1.a > 10)", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -7962,7 +8772,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 15 and (t1.a < 12 or t1.a > 10)" } @@ -7986,7 +8798,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 18, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -7995,6 +8809,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "max_c < 707", "filesort": { "sort_key": "t1.a, t1.b", @@ -8004,7 +8819,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 5" } @@ -8159,6 +8976,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "0 or (2,(subquery#3))", "nested_loop": [ { @@ -8173,8 +8991,10 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, - "filtered": 100, + "cost": "COST_REPLACED", + "filtered": 50, "attached_condition": "t2.b = 2", "first_match": "t1" } @@ -8184,6 +9004,7 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -8194,17 +9015,22 @@ EXPLAIN "key_length": "5", "used_key_parts": ["c"], "ref": ["func"], - "rows": 2, + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 5, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.c = 2" } @@ -8246,7 +9072,7 @@ SELECT d FROM v4 WHERE s > a id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1) -3 DEPENDENT SUBQUERY index_subquery key0 key0 5 func 2 Using where +3 DEPENDENT SUBQUERY index_subquery key0 key0 5 func 1 Using where 5 DERIVED t4 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort explain format=json SELECT * FROM t1 WHERE a IN ( SELECT b FROM v2 WHERE b < a OR b IN ( @@ -8257,6 +9083,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "0 or (2,(subquery#3))", "nested_loop": [ { @@ -8271,8 +9098,10 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, - "filtered": 100, + "cost": "COST_REPLACED", + "filtered": 50, "attached_condition": "t2.b = 2", "first_match": "t1" } @@ -8282,6 +9111,7 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -8292,11 +9122,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["func"], - "rows": 2, + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 5, + "cost": "COST_REPLACED", "having_condition": "s > 2", "filesort": { "sort_key": "t4.d", @@ -8306,7 +9139,9 @@ EXPLAIN "table": { "table_name": "t4", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -8361,23 +9196,29 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.b = 1", "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b = 1" } @@ -8416,12 +9257,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -8434,18 +9278,23 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "trigcond(v2.b is null) and trigcond(trigcond(t1.a is not null))", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -8471,23 +9320,29 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(v1.i <= 3)", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.i <= 3)" } @@ -8532,12 +9387,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.b,(subquery#2)) or t1.b = 100" } @@ -8547,6 +9405,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -8557,17 +9416,22 @@ EXPLAIN "key_length": "4", "used_key_parts": ["pk2"], "ref": ["func"], - "rows": 2, + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -8594,12 +9458,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.b,(subquery#3)) or t1.b = 100" } @@ -8609,6 +9476,7 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -8619,17 +9487,22 @@ EXPLAIN "key_length": "4", "used_key_parts": ["pk2"], "ref": ["func"], - "rows": 2, + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -8678,23 +9551,29 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 50", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 50" } @@ -8736,17 +9615,21 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.s < 50", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "s < 50", "filesort": { "sort_key": "t3.a", @@ -8756,7 +9639,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -8794,13 +9679,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -8819,18 +9705,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b = 2", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 2" } @@ -8864,13 +9755,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -8886,18 +9778,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.f = 2", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.f = 2" } @@ -8912,7 +9809,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 2, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.pk > 2" }, @@ -8922,6 +9821,7 @@ EXPLAIN "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -8931,7 +9831,9 @@ EXPLAIN "key": "PRIMARY", "key_length": "4", "used_key_parts": ["pk"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t.pk > 2" } @@ -8964,13 +9866,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -8986,18 +9889,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "sq.i = 3", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.i = 3" } @@ -9031,13 +9939,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -9053,18 +9962,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "sq.i = 2.71", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.i = 2.7100000381469727" } @@ -9093,13 +10007,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -9115,18 +10030,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "sq.i = 3.21", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.i = 3.21" } @@ -9155,13 +10075,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -9177,18 +10098,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "sq.i = 'aa'", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.i = 'aa'" } @@ -9219,13 +10145,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -9241,18 +10168,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "sq.i = '2007-05-28 00:00:00'", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.i = TIMESTAMP'2007-05-28 00:00:00'" } @@ -9281,13 +10213,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -9303,18 +10236,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "sq.i = '2007-05-28'", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.i = DATE'2007-05-28'" } @@ -9343,13 +10281,14 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "system", - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "materialized": { "unique": 1, "query_block": { @@ -9365,18 +10304,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "sq.i = '10:00:02'", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.i = TIME'10:00:02'" } @@ -9405,23 +10349,29 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "nullif(1,v1.i)", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "nullif(1,t1.i)" } @@ -9500,23 +10450,29 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c = 'foo'", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = 'foo'" } @@ -9531,12 +10487,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "1 = t2.a" } @@ -9561,23 +10520,29 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "((1,(subquery#2))) or v1.c = 'foo'", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -9591,12 +10556,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 128, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "1 = t2.a" } @@ -9737,12 +10705,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2 and t1.a is not null" } @@ -9756,11 +10727,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 7, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t2.b", "temporary_table": { @@ -9769,7 +10743,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b > 2" } @@ -9797,12 +10773,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2 and t1.a is not null" } @@ -9816,11 +10795,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 7, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t2.b", "temporary_table": { @@ -9829,7 +10811,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b > 2" } @@ -9860,12 +10844,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2 and t1.a is not null" } @@ -9879,18 +10866,23 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 7, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b > 2" } @@ -9917,12 +10909,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2 and t1.a is not null" } @@ -9936,11 +10931,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["m"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 7, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "m > 2", "filesort": { "sort_key": "t2.b", @@ -9950,7 +10948,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -9980,24 +10980,30 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.f > 0", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "f > 0", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -10028,6 +11034,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -10038,7 +11045,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["i1"], "ref": ["const"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "using_index": true } @@ -10048,7 +11057,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.i2 = 1" }, @@ -10058,12 +11069,15 @@ EXPLAIN "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.i2 = 1" } @@ -10096,24 +11110,30 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.f = 'a' or t.f = 'b'", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -10151,12 +11171,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.id2 is not null" } @@ -10170,12 +11193,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["id2"], "ref": ["test.t1.id2"], - "rows": 2, + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "vc.ct > 0", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "ct > 0", "filesort": { "sort_key": "t2.id2", @@ -10185,7 +11211,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -10250,12 +11278,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x = 1" } @@ -10265,7 +11296,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 2, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 1 and v1.b = 1 and v1.max_c > 30" }, @@ -10275,13 +11308,16 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c > 37 and max_c > 30", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.b = 1" } @@ -10335,12 +11371,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x = 1" } @@ -10350,7 +11389,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 2, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 1 and v1.b = 1 and v1.d = 1 and v1.max_c > 30" }, @@ -10360,13 +11401,16 @@ EXPLAIN "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c > 37 and max_c > 30", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.b = 1 and t1.d = 1" } @@ -10433,7 +11477,7 @@ WHERE d_tab.e>1 ; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where -1 PRIMARY ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 10 test.t1.a,test.t1.b 1 3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE (t1.a,t1.b) IN @@ -10452,12 +11496,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null" } @@ -10465,18 +11512,20 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ref", - "possible_keys": ["key0"], - "key": "key0", + "access_type": "eq_ref", + "possible_keys": ["distinct_key"], + "key": "distinct_key", "key_length": "10", "used_key_parts": ["e", "max_f"], "ref": ["test.t1.a", "test.t1.b"], - "rows": 2, + "loops": 5, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, - "first_match": "t1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_f > 18", "filesort": { "sort_key": "t2.e", @@ -10486,7 +11535,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e > 1" } @@ -10532,7 +11583,7 @@ WHERE d_tab.max_f<25 ; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where -1 PRIMARY ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 10 test.t1.a,test.t1.b 1 3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE (t1.a,t1.b) IN @@ -10551,12 +11602,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b < 25 and t1.a is not null and t1.b is not null" } @@ -10564,18 +11618,20 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ref", - "possible_keys": ["key0"], - "key": "key0", + "access_type": "eq_ref", + "possible_keys": ["distinct_key"], + "key": "distinct_key", "key_length": "10", "used_key_parts": ["e", "max_f"], "ref": ["test.t1.a", "test.t1.b"], - "rows": 2, + "loops": 5, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, - "first_match": "t1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_f > 18 and max_f < 25", "filesort": { "sort_key": "t2.e", @@ -10585,7 +11641,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -10649,12 +11707,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a is not null and t1.b is not null" } @@ -10668,24 +11729,30 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "max_f"], "ref": ["test.t1.a", "test.t1.b"], + "loops": 5, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "d_tab.e > 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t2.e", "temporary_table": { @@ -10694,7 +11761,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e > 1" } @@ -10765,12 +11834,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a is not null and t1.b is not null" } @@ -10784,24 +11856,30 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "max_f"], "ref": ["test.t1.a", "test.t1.b"], + "loops": 5, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "d_tab.max_f > 20", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_f > 20", "filesort": { "sort_key": "t2.e", @@ -10811,7 +11889,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -10873,17 +11953,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "dt.a = 2", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "a = 2", "filesort": { "sort_key": "t1.a", @@ -10893,7 +11977,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -10930,17 +12016,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "dt.a > 1", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "a > 1", "filesort": { "sort_key": "t1.a", @@ -10950,7 +12040,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 3" } @@ -10987,17 +12079,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "dt.a = 'ab'", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -11006,7 +12102,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -11042,17 +12140,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "dt.a = 1", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -11061,7 +12163,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -11117,12 +12221,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "1 in (0,t1.a) and t1.a is not null" } @@ -11136,11 +12243,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -11149,7 +12259,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "1 in (0,t1.a) and 1 in (0,t1.a)" } @@ -11185,12 +12297,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a in (1,t1.a) and t1.a is not null" } @@ -11204,11 +12319,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -11217,7 +12335,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a in (1,t1.a)" } @@ -11316,17 +12436,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a <= 2", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -11335,7 +12459,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a <= 2" } @@ -11362,12 +12488,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -11381,12 +12510,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["c"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 5, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = t.c and t.a >= 3", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -11395,7 +12527,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a >= 3" } @@ -11425,12 +12559,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -11438,18 +12575,23 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 5, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a = 2 and t2.a = t.c + 9", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2" } @@ -11499,17 +12641,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "case when tab2.max_a = 1 or tab2.max_a = 2 then 1 else 0 end = 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "case when max_a = 1 or max_a = 2 then 1 else 0 end = 1", "filesort": { "sort_key": "t1.b", @@ -11519,7 +12665,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -11556,17 +12704,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "case when tab2.max_a = 1 or tab2.max_a > 2 and tab2.max_a < 4 then 1 else 0 end = 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "case when max_a = 1 or max_a > 2 and max_a < 4 then 1 else 0 end = 1", "filesort": { "sort_key": "t1.b", @@ -11576,7 +12728,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -11613,17 +12767,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "case when tab2.max_a > 1 and (tab2.max_a = 2 or tab2.max_a > 2) then 1 else 0 end = 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "case when max_a > 1 and (max_a = 2 or max_a > 2) then 1 else 0 end = 1", "filesort": { "sort_key": "t1.b", @@ -11633,7 +12791,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -11670,17 +12830,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "case when tab2.b = 2 or tab2.b = 4 then 1 else 0 end = 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.b", "temporary_table": { @@ -11689,7 +12853,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "case when t1.b = 2 or t1.b = 4 then 1 else 0 end = 1" } @@ -11747,33 +12913,42 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 144, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.f is not null", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -11787,7 +12962,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 12, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f is not null" }, @@ -11830,23 +13007,29 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", - "rows": 16, + "loops": 1, + "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.f is not null", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f is not null" } @@ -11860,17 +13043,22 @@ EXPLAIN "key_length": "4", "used_key_parts": ["f"], "ref": ["test.t1.f"], - "rows": 2, + "loops": 8, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f is not null" } @@ -11915,12 +13103,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f2 < 2 and t1.f2 is not null" } @@ -11934,17 +13125,22 @@ EXPLAIN "key_length": "5", "used_key_parts": ["f2"], "ref": ["test.t1.f2"], - "rows": 2, + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f2 < 2" } @@ -11970,12 +13166,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f2 < 2 and t1.f2 is not null" } @@ -11989,18 +13188,23 @@ EXPLAIN "key_length": "5", "used_key_parts": ["f2"], "ref": ["test.t1.f2"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f2 < 2" } @@ -12050,12 +13254,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -12256,12 +13463,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v3.col1 = 123 and v3.col2 = 321", "materialized": { @@ -12271,6 +13481,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -12281,7 +13492,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["const"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -12292,6 +13505,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -12302,7 +13516,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["const"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -12340,17 +13556,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.s + 1 > 10 and v2.a > 1 and v2.a2 > 123", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "s + 1 > 10 and a2 > 123", "filesort": { "sort_key": "t1.a, f1(t1.a)", @@ -12360,7 +13580,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -12393,12 +13615,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t4", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t4.a + 1 > 10 and t4.b > 1 and t4.c > 123 and t4.a is not null and t4.b is not null and t4.c is not null" } @@ -12412,13 +13637,16 @@ EXPLAIN "key_length": "23", "used_key_parts": ["a", "f1(a)", "sum(b)"], "ref": ["test.t4.a", "test.t4.b", "test.t4.c"], + "loops": 3, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t4.c = ``.`sum(b)`", "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`f1(a)` > 1 and `sum(b)` > 123", "temporary_table": { "nested_loop": [ @@ -12426,7 +13654,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a + 1 > 10" } @@ -12481,7 +13711,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<5); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 +1 PRIMARY ref key0 key0 5 test.t2.a 1 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL @@ -12490,12 +13720,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 5 and t2.a is not null" } @@ -12509,7 +13742,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -12520,6 +13755,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -12529,7 +13765,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a < 5" } @@ -12543,6 +13781,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100", "filesort": { "sort_key": "t1.a, t1.b", @@ -12552,7 +13791,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a < 5" } @@ -12592,12 +13833,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 8" } @@ -12607,7 +13851,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 8" }, @@ -12623,6 +13869,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.b", @@ -12632,7 +13879,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 8" } @@ -12646,6 +13895,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100", "filesort": { "sort_key": "t1.b", @@ -12655,7 +13905,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 8 and t1.b > 10" } @@ -12694,12 +13946,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 8" } @@ -12709,7 +13964,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 8" }, @@ -12725,6 +13982,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.b", @@ -12734,7 +13992,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 8" } @@ -12748,6 +14008,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100", "filesort": { "sort_key": "t1.b", @@ -12757,7 +14018,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 8 and t1.b > 10" } @@ -12789,7 +14052,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.c>200); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL @@ -12798,12 +14061,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -12817,7 +14083,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 200", "materialized": { @@ -12829,6 +14097,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -12838,7 +14107,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9" } @@ -12852,6 +14123,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -12861,7 +14133,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10" } @@ -12894,7 +14168,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>110); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL @@ -12903,12 +14177,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 5 and t2.a is not null" } @@ -12922,7 +14199,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 110", "materialized": { @@ -12934,6 +14213,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300 and c > 110", "filesort": { "sort_key": "t1.a, t1.b", @@ -12943,7 +14223,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a < 5" } @@ -12957,6 +14239,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100 and c > 110", "filesort": { "sort_key": "t1.a, t1.b", @@ -12966,7 +14249,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a < 5" } @@ -13000,7 +14285,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL @@ -13009,12 +14294,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -13028,7 +14316,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b > 27 or v1.b < 19", "materialized": { @@ -13040,6 +14330,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -13049,7 +14340,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and (t1.b > 27 or t1.b < 19)" } @@ -13063,6 +14356,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100", "filesort": { "sort_key": "t1.a, t1.b", @@ -13072,7 +14366,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and (t1.b > 27 or t1.b < 19)" } @@ -13111,7 +14407,7 @@ explain select * from v1,t2 where (v1.a=t2.a) and ((v1.c>200) or (v1.c<105)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL @@ -13121,12 +14417,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -13140,7 +14439,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 200 or v1.c < 105", "materialized": { @@ -13152,6 +14453,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300 and (c > 200 or c < 105)", "filesort": { "sort_key": "t1.a, t1.b", @@ -13161,7 +14463,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9" } @@ -13175,6 +14479,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100 and (c > 200 or c < 105)", "filesort": { "sort_key": "t1.a, t1.b", @@ -13184,7 +14489,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10" } @@ -13255,12 +14562,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -13269,7 +14579,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 3 or v1.a = 1 and v1.c < 110" }, @@ -13286,6 +14598,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300 and (t1.a > 3 and c > 110 or t1.a = 1 and c < 110)", "filesort": { "sort_key": "t1.a, t1.b", @@ -13295,7 +14608,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and (t1.a > 3 or t1.a = 1)" } @@ -13309,6 +14624,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100 and (t1.a > 3 and c > 110 or t1.a = 1 and c < 110)", "filesort": { "sort_key": "t1.a, t1.b", @@ -13318,7 +14634,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and (t1.a > 3 or t1.a = 1)" } @@ -13399,7 +14717,7 @@ where ((d1.a<4) and (d1.c<200))); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.b 2 Using where +1 PRIMARY ref key1 key1 5 test.t2.b 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL @@ -13418,12 +14736,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b is not null" } @@ -13432,12 +14753,14 @@ EXPLAIN "table": { "table_name": "", "access_type": "ref", - "possible_keys": ["key0"], - "key": "key0", + "possible_keys": ["key1"], + "key": "key1", "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t2.b"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.c = 909 and t2.b > 13 or d1.a < 4 and d1.c < 200", "materialized": { @@ -13449,6 +14772,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300 and (t1.b > 13 or t1.a < 4 and c < 200)", "filesort": { "sort_key": "t1.a, t1.b", @@ -13458,7 +14782,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and (t1.b > 13 or t1.a < 4)" } @@ -13472,6 +14798,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 100 and (t1.b > 13 or t1.a < 4 and c < 200)", "filesort": { "sort_key": "t1.a, t1.b", @@ -13481,7 +14808,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and (t1.b > 13 or t1.a < 4)" } @@ -13524,7 +14853,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<5); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 +1 PRIMARY ref key0 key0 5 test.t2.a 1 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL @@ -13533,12 +14862,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 5 and t2.a is not null" } @@ -13552,7 +14884,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -13563,6 +14897,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -13572,7 +14907,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a < 5" } @@ -13586,6 +14923,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -13595,7 +14933,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a < 5" } @@ -13637,12 +14977,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 6" } @@ -13652,7 +14995,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 6" }, @@ -13668,6 +15013,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200", "filesort": { "sort_key": "t1.b", @@ -13677,7 +15023,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 6" } @@ -13691,6 +15039,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.b", @@ -13700,7 +15049,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 6 and t1.b > 10" } @@ -13741,12 +15092,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a = 6" } @@ -13756,7 +15110,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a = 6" }, @@ -13772,6 +15128,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200", "filesort": { "sort_key": "t1.b", @@ -13781,7 +15138,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 6" } @@ -13795,6 +15154,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.b", @@ -13804,7 +15164,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 6 and t1.b > 10" } @@ -13840,7 +15202,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.c>500); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL @@ -13849,12 +15211,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -13868,7 +15233,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 500", "materialized": { @@ -13880,6 +15247,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and c > 500", "filesort": { "sort_key": "t1.a, t1.b", @@ -13889,7 +15257,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9" } @@ -13903,6 +15273,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300 and c > 500", "filesort": { "sort_key": "t1.a, t1.b", @@ -13912,7 +15283,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10" } @@ -13945,7 +15318,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>500); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL @@ -13954,12 +15327,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 5 and t2.a is not null" } @@ -13973,7 +15349,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 500", "materialized": { @@ -13985,6 +15363,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and c > 500", "filesort": { "sort_key": "t1.a, t1.b", @@ -13994,7 +15373,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a < 5" } @@ -14008,6 +15389,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300 and c > 500", "filesort": { "sort_key": "t1.a, t1.b", @@ -14017,7 +15399,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a < 5" } @@ -14053,7 +15437,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and ((v1.b>27) or (v1.b<19)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL @@ -14062,12 +15446,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -14081,7 +15468,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b > 27 or v1.b < 19", "materialized": { @@ -14093,6 +15482,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14102,7 +15492,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and (t1.b > 27 or t1.b < 19)" } @@ -14116,6 +15508,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -14125,7 +15518,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and (t1.b > 27 or t1.b < 19)" } @@ -14164,7 +15559,7 @@ explain select * from v1,t2 where (v1.a=t2.a) and ((v1.c<400) or (v1.c>800)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL @@ -14174,12 +15569,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a is not null" } @@ -14193,7 +15591,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c < 400 or v1.c > 800", "materialized": { @@ -14205,6 +15605,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and (c < 400 or c > 800)", "filesort": { "sort_key": "t1.a, t1.b", @@ -14214,7 +15615,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9" } @@ -14228,6 +15631,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300 and (c < 400 or c > 800)", "filesort": { "sort_key": "t1.a, t1.b", @@ -14237,7 +15641,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10" } @@ -14306,12 +15712,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -14320,7 +15729,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 9, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a > 1 or v1.a = 1 and v1.c > 500" }, @@ -14337,6 +15748,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and (t1.a > 1 and c < 500 or t1.a = 1 and c > 500)", "filesort": { "sort_key": "t1.a, t1.b", @@ -14346,7 +15758,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and (t1.a > 1 or t1.a = 1)" } @@ -14360,6 +15774,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300 and (t1.a > 1 and c < 500 or t1.a = 1 and c > 500)", "filesort": { "sort_key": "t1.a, t1.b", @@ -14369,7 +15784,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and (t1.a > 1 or t1.a = 1)" } @@ -14446,7 +15863,7 @@ where ((d1.a>4) and (d1.c>500))); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.b 2 Using where +1 PRIMARY ref key1 key1 5 test.t2.b 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL @@ -14465,12 +15882,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b is not null" } @@ -14479,12 +15899,14 @@ EXPLAIN "table": { "table_name": "", "access_type": "ref", - "possible_keys": ["key0"], - "key": "key0", + "possible_keys": ["key1"], + "key": "key1", "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t2.b"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.c = 988 and t2.b > 13 or d1.a > 4 and d1.c > 500", "materialized": { @@ -14496,6 +15918,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and (t1.b > 13 or t1.a > 4 and c > 500)", "filesort": { "sort_key": "t1.a, t1.b", @@ -14505,7 +15928,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and (t1.b > 13 or t1.a > 4)" } @@ -14519,6 +15944,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 300 and (t1.b > 13 or t1.a > 4 and c > 500)", "filesort": { "sort_key": "t1.a, t1.b", @@ -14528,7 +15954,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and (t1.b > 13 or t1.a > 4)" } @@ -14582,12 +16010,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 5 and t2.a is not null" } @@ -14601,7 +16032,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 200", "materialized": { @@ -14613,6 +16046,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14622,7 +16056,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 5" } @@ -14636,12 +16072,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "__5.a > 5 and __5.c > 200", "materialized": { @@ -14653,6 +16092,7 @@ EXPLAIN { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "c < 300 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14662,7 +16102,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a > 5" } @@ -14676,6 +16118,7 @@ EXPLAIN "query_block": { "select_id": 5, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c < 530 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14685,7 +16128,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 3 and t1.a > 5" } @@ -14748,12 +16193,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 4 and t2.a is not null" } @@ -14767,7 +16215,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c < 200", "materialized": { @@ -14779,6 +16229,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and c < 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14788,7 +16239,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 4" } @@ -14802,6 +16255,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c < 500 and c < 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14811,7 +16265,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 3 and t1.a > 4" } @@ -14825,6 +16281,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 300 and c < 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14834,7 +16291,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a > 4" } @@ -14886,12 +16345,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 5 and t2.a is not null" } @@ -14905,7 +16367,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 200", "materialized": { @@ -14917,6 +16381,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14926,7 +16391,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 5" } @@ -14940,6 +16407,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 300 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14949,7 +16417,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a > 5" } @@ -14963,6 +16433,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 530 and c > 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -14972,7 +16443,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 3 and t1.a > 5" } @@ -15026,12 +16499,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 4 and t2.a is not null" } @@ -15045,7 +16521,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c < 200", "materialized": { @@ -15057,6 +16535,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 200 and c < 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -15066,7 +16545,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 4" } @@ -15080,6 +16561,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c < 500 and c < 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -15089,7 +16571,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 3 and t1.a > 4" } @@ -15103,6 +16587,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 300 and c < 200", "filesort": { "sort_key": "t1.a, t1.b", @@ -15112,7 +16597,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a > 4" } @@ -15154,7 +16641,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<150); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 4 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort @@ -15164,12 +16651,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 4 and t2.a is not null" } @@ -15183,7 +16673,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c < 150", "materialized": { @@ -15195,6 +16687,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300 and c < 150", "filesort": { "sort_key": "t1.a, t1.b", @@ -15204,7 +16697,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a > 4" } @@ -15218,6 +16713,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c < 500 and c < 150", "filesort": { "sort_key": "t1.a, t1.b", @@ -15227,7 +16723,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 7 and t1.a > 4" } @@ -15241,6 +16739,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c > 150 and c < 150", "filesort": { "sort_key": "t1.a, t1.b", @@ -15250,7 +16749,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 4" } @@ -15290,7 +16791,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT ALL NULL NULL NULL NULL 18 Using where 4 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort @@ -15302,12 +16803,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 4 and t2.a is not null" } @@ -15321,7 +16825,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c < 130", "materialized": { @@ -15333,6 +16839,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300 and c < 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -15342,7 +16849,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a > 4" } @@ -15356,12 +16865,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "__5.a > 4 and __5.c < 130", "materialized": { @@ -15373,6 +16885,7 @@ EXPLAIN { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "c > 150 and c < 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -15382,7 +16895,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 4" } @@ -15396,6 +16911,7 @@ EXPLAIN "query_block": { "select_id": 5, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c < 500 and c < 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -15405,7 +16921,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 7 and t1.a > 4" } @@ -15470,12 +16988,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 4 and t2.a is not null" } @@ -15489,7 +17010,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c < 130", "materialized": { @@ -15501,6 +17024,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 300 and c < 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -15510,7 +17034,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a > 4" } @@ -15524,12 +17050,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "__6.a > 4 and __6.c < 130", "materialized": { @@ -15541,6 +17070,7 @@ EXPLAIN { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "having_condition": "c > 150 and c < 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -15550,7 +17080,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 4" } @@ -15564,6 +17096,7 @@ EXPLAIN "query_block": { "select_id": 5, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c < 500 and c < 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -15573,7 +17106,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 7 and t1.a > 4" } @@ -15596,6 +17131,7 @@ EXPLAIN "query_block": { "select_id": 6, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c < 120 and c < 130", "filesort": { "sort_key": "t1.a, t1.b", @@ -15605,7 +17141,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 7 and t1.a > 4" } @@ -15648,7 +17186,7 @@ a b c a b c explain select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 4 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort @@ -15658,12 +17196,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 4 and t2.a is not null" } @@ -15677,12 +17218,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.c < 150", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 150", "filesort": { "sort_key": "v1.a, v1.b", @@ -15692,7 +17236,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 7 and v1.a > 4", "materialized": { @@ -15704,6 +17250,7 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -15713,7 +17260,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a < 7 and t1.a > 4" } @@ -15727,6 +17276,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 120", "filesort": { "sort_key": "t1.a, t1.b", @@ -15736,7 +17286,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a < 7 and t1.a > 4" } @@ -15786,7 +17338,7 @@ a b c a b c explain select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 4 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort @@ -15796,12 +17348,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 4 and t2.a is not null" } @@ -15815,12 +17370,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.c < 150", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c < 150", "filesort": { "sort_key": "v1.a, v1.b", @@ -15830,7 +17388,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 7 and v1.a > 4", "materialized": { @@ -15842,6 +17402,7 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "c < 300", "filesort": { "sort_key": "t1.a, t1.b", @@ -15851,7 +17412,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a < 7 and t1.a > 4" } @@ -15865,6 +17428,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c > 150", "filesort": { "sort_key": "t1.a, t1.b", @@ -15874,7 +17438,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a < 7 and t1.a > 4" } @@ -15921,7 +17487,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.b>12) and (v1.c<450); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 INTERSECT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL @@ -15930,12 +17496,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 4 and t2.a is not null" } @@ -15949,7 +17518,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b > 12 and v1.c < 450", "materialized": { @@ -15961,6 +17532,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 300 and t1.b > 12 and c < 450", "filesort": { "sort_key": "t1.a", @@ -15970,7 +17542,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 4" } @@ -15984,6 +17558,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c > 200 and t1.a > 4 and c < 450", "filesort": { "sort_key": "t1.b", @@ -15993,7 +17568,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b < 21 and t1.b > 12" } @@ -16033,7 +17610,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and (v1.a<2) and (v1.b<30) and (v1.c>450); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL @@ -16042,12 +17619,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a < 2 and t2.a is not null" } @@ -16061,7 +17641,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b < 30 and v1.c > 450", "materialized": { @@ -16073,6 +17655,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 300 and t1.b < 30 and c > 450", "filesort": { "sort_key": "t1.a", @@ -16082,7 +17665,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 20 and t1.a < 2" } @@ -16096,6 +17681,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c > 150 and t1.a < 2 and c > 450", "filesort": { "sort_key": "t1.b", @@ -16105,7 +17691,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 7 and t1.b < 30" } @@ -16147,7 +17735,7 @@ a b c a b c explain select * from v1,t2 where (v1.a=t2.a) and ((v1.a<2) or (v1.a<5)) and (v1.c>450); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort 3 EXCEPT t1 ALL NULL NULL NULL NULL 18 Using where; Using temporary; Using filesort NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL @@ -16156,12 +17744,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t2.a < 2 or t2.a < 5) and t2.a is not null" } @@ -16175,7 +17766,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 450", "materialized": { @@ -16187,6 +17780,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 300 and c > 450", "filesort": { "sort_key": "t1.a", @@ -16196,7 +17790,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 20 and (t1.a < 2 or t1.a < 5)" } @@ -16210,6 +17806,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "having_condition": "c > 150 and (t1.a < 2 or t1.a < 5) and c > 450", "filesort": { "sort_key": "t1.b", @@ -16219,7 +17816,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 7" } @@ -16272,12 +17871,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a > 1 and t2.a is not null" } @@ -16291,7 +17893,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 9, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.b > 12 and v1.c > 400", "materialized": { @@ -16303,6 +17907,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "c > 100 and t1.b > 12 and c > 400", "filesort": { "sort_key": "t1.a", @@ -16312,7 +17917,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 9 and t1.a > 1" } @@ -16326,6 +17933,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "having_condition": "c < 800 and t1.a > 1 and c > 400", "filesort": { "sort_key": "t1.b", @@ -16335,7 +17943,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 3 and t1.b > 12" } @@ -16349,6 +17959,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "c > 300 and c > 400", "filesort": { "sort_key": "t1.a, t1.b", @@ -16358,7 +17969,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 10 and t1.a > 1 and t1.b > 12" } @@ -16409,19 +18022,22 @@ a b max_c a b c explain select * from v1,t2 where (v1.b=t2.b) and (v1.a<5); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.b 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.b 1 Using where 2 DERIVED t3 range i1 i1 5 NULL 5 Using index condition explain format=json select * from v1,t2 where (v1.b=t2.b) and (v1.a<5); EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b is not null" } @@ -16435,12 +18051,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t2.b"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 5", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -16450,7 +18069,9 @@ EXPLAIN "key": "i1", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t3.a > 0 and t3.a < 5" } @@ -16486,7 +18107,7 @@ a b c a b c explain select * from v1,t2 where (v1.b=t2.b) and (v1.a<4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 5 test.t2.b 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.b 1 Using where 2 DERIVED t3 range i1 i1 5 NULL 2 Using index condition 3 UNION t3 range i1 i1 5 NULL 1 Using index condition NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -16495,12 +18116,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b is not null" } @@ -16514,7 +18138,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t2.b"], - "rows": 2, + "loops": 9, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 4", "materialized": { @@ -16526,6 +18152,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -16535,7 +18162,9 @@ EXPLAIN "key": "i1", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t3.a > 1 and t3.a < 4" } @@ -16547,6 +18176,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -16556,7 +18186,9 @@ EXPLAIN "key": "i1", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t3.a > 2 and t3.a < 4" } @@ -16605,12 +18237,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.b is not null" } @@ -16624,7 +18259,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t2.b"], + "loops": 9, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.a < 3", "materialized": { @@ -16636,6 +18273,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -16645,7 +18283,9 @@ EXPLAIN "key": "i1", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t3.a > 1 and t3.a < 3" } @@ -16657,6 +18297,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "t3.a < 3", "filesort": { "sort_key": "t3.b", @@ -16666,7 +18307,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.b < 21" } @@ -16738,17 +18381,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a > 2 and t.c in ('aa','bb','cc')", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -16764,7 +18411,9 @@ EXPLAIN "table_name": "t2", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 80, "attached_condition": "t2.a > 2 and t2.c in ('aa','bb','cc')" } @@ -16853,12 +18502,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 32, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a > 2 and t.c in ('aa','bb','cc')", "materialized": { @@ -16868,6 +18520,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -16883,7 +18536,9 @@ EXPLAIN "table_name": "t2", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 80, "attached_condition": "t2.a > 2 and t2.c in ('aa','bb','cc')" } @@ -16897,6 +18552,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -16912,7 +18568,9 @@ EXPLAIN "table_name": "t2", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 80, "attached_condition": "t2.a > 2" } @@ -16961,12 +18619,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c in ('aa','bb','cc') and t1.a is not null and t1.c is not null" } @@ -16980,11 +18641,14 @@ EXPLAIN "key_length": "24", "used_key_parts": ["a", "c"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 8, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -16999,7 +18663,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.c in ('aa','bb','cc')" } @@ -17101,12 +18767,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 48, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a > 2 and t.c in ('aa','bb','cc')", "materialized": { @@ -17116,6 +18785,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -17131,7 +18801,9 @@ EXPLAIN "table_name": "t2", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 80, "attached_condition": "t2.a > 2 and t2.c in ('aa','bb','cc')" } @@ -17145,6 +18817,7 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "UNION", + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -17160,7 +18833,9 @@ EXPLAIN "table_name": "t2", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 80, "attached_condition": "t2.a > 2" } @@ -17174,6 +18849,7 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "UNION", + "cost": "COST_REPLACED", "having_condition": "t2.c in ('aa','bb','cc')", "filesort": { "sort_key": "t2.a", @@ -17184,7 +18860,9 @@ EXPLAIN "table_name": "t2", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 80, "attached_condition": "t2.a > 2" } @@ -17250,17 +18928,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a > 2 and t.c in ('aa','bb','cc')", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -17276,7 +18958,9 @@ EXPLAIN "table_name": "t2", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 80, "attached_condition": "t2.a > 2 and t2.c in ('aa','bb','cc')" } @@ -17338,17 +19022,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a > 2 and t.c in ('aa','bb','cc')", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -17364,7 +19052,9 @@ EXPLAIN "table_name": "t2", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 80, "attached_condition": "t2.a > 2" } @@ -17426,17 +19116,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t.a > 2 and t.c in ('aa','bb','cc')", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -17456,7 +19150,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 20, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.c in ('aa','bb','cc')" } @@ -17528,7 +19224,7 @@ on t1.a=t.a where t1.b < 3; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 range idx_b idx_b 5 NULL 4 100.00 Using index condition; Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 100.00 +1 PRIMARY ref key0 key0 5 test.t1.a 1 100.00 2 LATERAL DERIVED t2 ref idx_a idx_a 5 test.t1.a 1 100.00 Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`s` AS `s`,`t`.`m` AS `m` from `test`.`t1` join (/* select#2 */ select `test`.`t2`.`a` AS `a`,sum(`test`.`t2`.`b`) AS `s`,min(`test`.`t2`.`c`) AS `m` from `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` group by `test`.`t2`.`a`) `t` where `t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` < 3 @@ -17541,6 +19237,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -17550,7 +19247,9 @@ EXPLAIN "key": "idx_b", "key_length": "5", "used_key_parts": ["b"], + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.b < 3", "attached_condition": "t1.a is not null" @@ -17565,12 +19264,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "outer_ref_condition": "t1.a is not null", "nested_loop": [ { @@ -17582,7 +19284,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t1.a"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -17649,7 +19353,7 @@ on t1.a=t.a where t1.b <= 5; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL idx_b NULL NULL NULL 12 83.33 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 100.00 +1 PRIMARY ref key0 key0 5 test.t1.a 1 100.00 2 LATERAL DERIVED t2 ref idx_a idx_a 5 test.t1.a 1 100.00 Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`s` AS `s`,`t`.`m` AS `m` from `test`.`t1` join (/* select#2 */ select `test`.`t2`.`a` AS `a`,sum(`test`.`t2`.`b`) AS `s`,min(`test`.`t2`.`b`) AS `m` from `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` group by `test`.`t2`.`a`) `t` where `t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <= 5 @@ -17662,13 +19366,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", "possible_keys": ["idx_b"], + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 83.33333588, "attached_condition": "t1.b <= 5 and t1.a is not null" } @@ -17682,12 +19389,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t1.a"], - "rows": 2, + "loops": 10, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "outer_ref_condition": "t1.a is not null", "nested_loop": [ { @@ -17699,7 +19409,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t1.a"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -17764,10 +19476,10 @@ from t1 left join on t1.a=t.a; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 -1 PRIMARY ref key0 key0 5 test.t1.a 9 100.00 Using where -2 DERIVED t2 ALL idx_a NULL NULL NULL 90 100.00 Using temporary; Using filesort +1 PRIMARY ref key0 key0 5 test.t1.a 1 100.00 Using where +2 LATERAL DERIVED t2 ref idx_a idx_a 5 test.t1.a 1 100.00 Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t1` left join (/* select#2 */ select `test`.`t2`.`a` AS `a`,max(`test`.`t2`.`b`) AS `max`,min(`test`.`t2`.`b`) AS `min` from `test`.`t2` group by `test`.`t2`.`a`) `t` on(`t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`a` is not null) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t1` left join (/* select#2 */ select `test`.`t2`.`a` AS `a`,max(`test`.`t2`.`b`) AS `max`,min(`test`.`t2`.`b`) AS `min` from `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` group by `test`.`t2`.`a`) `t` on(`t`.`a` = `test`.`t1`.`a` and `test`.`t1`.`a` is not null) where 1 explain format=json select t1.a,t.max,t.min from t1 left join (select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) t @@ -17776,13 +19488,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -17795,28 +19510,34 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t1.a"], - "rows": 9, + "loops": 12, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "trigcond(trigcond(t1.a is not null))", "materialized": { + "lateral": 1, "query_block": { "select_id": 2, - "filesort": { - "sort_key": "t2.a", - "temporary_table": { - "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "ALL", - "possible_keys": ["idx_a"], - "rows": 90, - "filtered": 100 - } - } - ] + "cost": "COST_REPLACED", + "outer_ref_condition": "t1.a is not null", + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "ref", + "possible_keys": ["idx_a"], + "key": "idx_a", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t1.a"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100 + } } - } + ] } } } @@ -17865,7 +19586,7 @@ on t3.a=t.a and t3.c=t.c where t3.b > 15; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 range idx_b idx_b 5 NULL 2 100.00 Using index condition; Using where -1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 2 100.00 +1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 1 100.00 2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 100.00 Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`a` = `test`.`t3`.`a` and `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`a`,`test`.`t4`.`c`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` > 15 @@ -17878,6 +19599,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -17887,7 +19609,9 @@ EXPLAIN "key": "idx_b", "key_length": "5", "used_key_parts": ["b"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t3.b > 15", "attached_condition": "t3.a is not null and t3.c is not null" @@ -17902,12 +19626,15 @@ EXPLAIN "key_length": "133", "used_key_parts": ["a", "c"], "ref": ["test.t3.a", "test.t3.c"], - "rows": 2, + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "outer_ref_condition": "t3.a is not null and t3.c is not null", "nested_loop": [ { @@ -17919,7 +19646,9 @@ EXPLAIN "key_length": "133", "used_key_parts": ["a", "c"], "ref": ["test.t3.a", "test.t3.c"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -17954,10 +19683,10 @@ on t3.a=t.a and t3.c=t.c where t3.b <= 15; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL idx_b NULL NULL NULL 12 83.33 Using where -1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 4 100.00 -2 DERIVED t4 ALL idx NULL NULL NULL 40 100.00 Using temporary; Using filesort +1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 1 100.00 +2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 100.00 Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` group by `test`.`t4`.`a`,`test`.`t4`.`c`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` <= 15 +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`a` = `test`.`t3`.`a` and `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`a`,`test`.`t4`.`c`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` <= 15 explain format=json select t3.a,t3.c,t.max,t.min from t3 join (select a, c, max(b) max, min(b) min from t4 group by a,c) t @@ -17967,13 +19696,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", "possible_keys": ["idx_b"], + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 83.33333588, "attached_condition": "t3.b <= 15 and t3.a is not null and t3.c is not null" } @@ -17987,27 +19719,33 @@ EXPLAIN "key_length": "133", "used_key_parts": ["a", "c"], "ref": ["test.t3.a", "test.t3.c"], - "rows": 4, + "loops": 10, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { + "lateral": 1, "query_block": { "select_id": 2, - "filesort": { - "sort_key": "t4.a, t4.c", - "temporary_table": { - "nested_loop": [ - { - "table": { - "table_name": "t4", - "access_type": "ALL", - "possible_keys": ["idx"], - "rows": 40, - "filtered": 100 - } - } - ] + "cost": "COST_REPLACED", + "outer_ref_condition": "t3.a is not null and t3.c is not null", + "nested_loop": [ + { + "table": { + "table_name": "t4", + "access_type": "ref", + "possible_keys": ["idx"], + "key": "idx", + "key_length": "133", + "used_key_parts": ["a", "c"], + "ref": ["test.t3.a", "test.t3.c"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100 + } } - } + ] } } } @@ -18038,7 +19776,7 @@ on t3.a=t.a and t3.c=t.c where t3.b > 15; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 range idx_b idx_b 5 NULL 2 100.00 Using index condition; Using where -1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 2 100.00 +1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 1 100.00 2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 100.00 Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`a` = `test`.`t3`.`a` and `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`c`,`test`.`t4`.`a`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` > 15 @@ -18051,6 +19789,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -18060,7 +19799,9 @@ EXPLAIN "key": "idx_b", "key_length": "5", "used_key_parts": ["b"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t3.b > 15", "attached_condition": "t3.a is not null and t3.c is not null" @@ -18075,12 +19816,15 @@ EXPLAIN "key_length": "133", "used_key_parts": ["a", "c"], "ref": ["test.t3.a", "test.t3.c"], - "rows": 2, + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "outer_ref_condition": "t3.a is not null and t3.c is not null", "nested_loop": [ { @@ -18092,7 +19836,9 @@ EXPLAIN "key_length": "133", "used_key_parts": ["a", "c"], "ref": ["test.t3.a", "test.t3.c"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -18127,10 +19873,10 @@ on t3.a=t.a and t3.c=t.c where t3.b <= 15; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL idx_b NULL NULL NULL 12 83.33 Using where -1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 4 100.00 -2 DERIVED t4 ALL idx NULL NULL NULL 40 100.00 Using temporary; Using filesort +1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 1 100.00 +2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 100.00 Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` group by `test`.`t4`.`c`,`test`.`t4`.`a`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` <= 15 +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t3` join (/* select#2 */ select `test`.`t4`.`a` AS `a`,`test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`a` = `test`.`t3`.`a` and `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`c`,`test`.`t4`.`a`) `t` where `t`.`a` = `test`.`t3`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t3`.`b` <= 15 explain format=json select t3.a,t3.c,t.max,t.min from t3 join (select a, c, max(b) max, min(b) min from t4 group by c,a) t @@ -18140,13 +19886,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", "possible_keys": ["idx_b"], + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 83.33333588, "attached_condition": "t3.b <= 15 and t3.a is not null and t3.c is not null" } @@ -18160,27 +19909,33 @@ EXPLAIN "key_length": "133", "used_key_parts": ["a", "c"], "ref": ["test.t3.a", "test.t3.c"], - "rows": 4, + "loops": 10, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { + "lateral": 1, "query_block": { "select_id": 2, - "filesort": { - "sort_key": "t4.c, t4.a", - "temporary_table": { - "nested_loop": [ - { - "table": { - "table_name": "t4", - "access_type": "ALL", - "possible_keys": ["idx"], - "rows": 40, - "filtered": 100 - } - } - ] + "cost": "COST_REPLACED", + "outer_ref_condition": "t3.a is not null and t3.c is not null", + "nested_loop": [ + { + "table": { + "table_name": "t4", + "access_type": "ref", + "possible_keys": ["idx"], + "key": "idx", + "key_length": "133", + "used_key_parts": ["a", "c"], + "ref": ["test.t3.a", "test.t3.c"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100 + } } - } + ] } } } @@ -18224,7 +19979,7 @@ where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 range idx idx 133 NULL 2 100.00 Using index condition; Using where 1 PRIMARY t3 ref idx_a idx_a 5 test.t2.a 1 100.00 Using where -1 PRIMARY ref key0 key0 128 test.t3.c 2 100.00 +1 PRIMARY ref key0 key0 128 test.t3.c 1 100.00 2 LATERAL DERIVED t4 ref idx_c idx_c 128 test.t3.c 2 100.00 Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`t`.`c` AS `t_c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` where `test`.`t4`.`c` = `test`.`t3`.`c` group by `test`.`t4`.`c`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` between 80 and 85 and `test`.`t2`.`c` in ('y','z') @@ -18235,6 +19990,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -18244,7 +20000,9 @@ EXPLAIN "key": "idx", "key_length": "133", "used_key_parts": ["c", "b"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t2.b between 80 and 85 and t2.c in ('y','z')", "attached_condition": "t2.a is not null" @@ -18259,7 +20017,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.c is not null" } @@ -18273,12 +20033,15 @@ EXPLAIN "key_length": "128", "used_key_parts": ["c"], "ref": ["test.t3.c"], - "rows": 2, + "loops": 3, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "outer_ref_condition": "t3.c is not null", "nested_loop": [ { @@ -18290,7 +20053,9 @@ EXPLAIN "key_length": "128", "used_key_parts": ["c"], "ref": ["test.t3.c"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -18395,12 +20160,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 90, + "cost": "COST_REPLACED", "filtered": 60, "attached_condition": "t2.b < 40 and t2.a is not null" } @@ -18414,7 +20182,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 53.99999991, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.c is not null" } @@ -18428,11 +20198,14 @@ EXPLAIN "key_length": "128", "used_key_parts": ["c"], "ref": ["test.t3.c"], + "loops": 80.99999987, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t4.c", "temporary_table": { @@ -18442,7 +20215,9 @@ EXPLAIN "table_name": "t4", "access_type": "ALL", "possible_keys": ["idx_c"], + "loops": 1, "rows": 160, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -18496,7 +20271,7 @@ where t2.b between 80 and 85 and t2.c in ('y','z') and t2.a=t3.a and t3.c=t.c; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 range idx idx 133 NULL 2 100.00 Using index condition; Using where 1 PRIMARY t3 ref idx_a idx_a 5 test.t2.a 1 100.00 Using where -1 PRIMARY ref key0 key0 128 test.t3.c 2 100.00 +1 PRIMARY ref key0 key0 128 test.t3.c 1 100.00 2 LATERAL DERIVED t4 ref idx_c idx_c 128 test.t3.c 2 100.00 Using temporary Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`t`.`c` AS `c`,`t`.`b` AS `b`,`t`.`sum(b) over (partition by c)` AS `sum(b) over (partition by c)` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,`test`.`t4`.`b` AS `b`,sum(`test`.`t4`.`b`) over ( partition by `test`.`t4`.`c`) AS `sum(b) over (partition by c)` from `test`.`t4` where `test`.`t4`.`c` = `test`.`t3`.`c`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` between 80 and 85 and `test`.`t2`.`c` in ('y','z') @@ -18507,6 +20282,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -18516,7 +20292,9 @@ EXPLAIN "key": "idx", "key_length": "133", "used_key_parts": ["c", "b"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t2.b between 80 and 85 and t2.c in ('y','z')", "attached_condition": "t2.a is not null" @@ -18531,7 +20309,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.c is not null" } @@ -18545,12 +20325,15 @@ EXPLAIN "key_length": "128", "used_key_parts": ["c"], "ref": ["test.t3.c"], - "rows": 2, + "loops": 3, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "outer_ref_condition": "t3.c is not null", "window_functions_computation": { "sorts": [ @@ -18571,7 +20354,9 @@ EXPLAIN "key_length": "128", "used_key_parts": ["c"], "ref": ["test.t3.c"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -18918,12 +20703,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 90, + "cost": "COST_REPLACED", "filtered": 60, "attached_condition": "t2.b < 40 and t2.a is not null" } @@ -18937,7 +20725,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], + "loops": 53.99999991, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.c is not null" } @@ -18951,11 +20741,14 @@ EXPLAIN "key_length": "128", "used_key_parts": ["c"], "ref": ["test.t3.c"], + "loops": 80.99999987, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -18971,7 +20764,9 @@ EXPLAIN "table_name": "t4", "access_type": "ALL", "possible_keys": ["idx_c"], + "loops": 1, "rows": 160, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -19023,7 +20818,7 @@ a c explain extended SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 ) and a < 2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t4 range a a 5 NULL 1 100.00 Using index condition; Using where -1 PRIMARY ref key0 key0 128 test.t4.c 2 100.00 FirstMatch(t4) +1 PRIMARY ref key0 key0 128 test.t4.c 1 100.00 FirstMatch(t4) 3 LATERAL DERIVED t3 ref c c 128 test.t4.c 2 100.00 3 LATERAL DERIVED eq_ref distinct_key distinct_key 4 func 1 100.00 4 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 100.00 @@ -19035,6 +20830,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -19044,7 +20840,9 @@ EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t4.a < 2", "attached_condition": "t4.c is not null" @@ -19059,13 +20857,16 @@ EXPLAIN "key_length": "128", "used_key_parts": ["c"], "ref": ["test.t4.c"], - "rows": 2, + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "first_match": "t4", "materialized": { "lateral": 1, "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "const_condition": "1", "outer_ref_condition": "t4.c is not null", "nested_loop": [ @@ -19078,7 +20879,9 @@ EXPLAIN "key_length": "128", "used_key_parts": ["c"], "ref": ["test.t4.c"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -19102,7 +20905,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -19111,7 +20916,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 3, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -19187,7 +20994,7 @@ DROP TABLE t1; CREATE TABLE t1 (pk1 INT PRIMARY KEY, f INT) ENGINE=Aria; INSERT INTO t1 VALUES (1,0),(2,0); CREATE TABLE t2 (pk2 INT PRIMARY KEY) ENGINE=Aria; -INSERT INTO t2 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (1),(2),(3),(11),(12),(13); CREATE VIEW v2 AS SELECT pk2, COUNT(*) AS cnt FROM t2 GROUP BY pk2; SELECT * FROM t1 INNER JOIN v2 ON pk1 = pk2 WHERE f <> 5; pk1 f pk2 cnt @@ -19196,7 +21003,7 @@ pk1 f pk2 cnt EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN v2 ON pk1 = pk2 WHERE f <> 5; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 2 100.00 Using where -1 PRIMARY ref key0 key0 4 test.t1.pk1 2 100.00 +1 PRIMARY ref key0 key0 4 test.t1.pk1 1 100.00 2 LATERAL DERIVED t2 eq_ref PRIMARY PRIMARY 4 test.t1.pk1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`f` AS `f`,`v2`.`pk2` AS `pk2`,`v2`.`cnt` AS `cnt` from `test`.`t1` join `test`.`v2` where `v2`.`pk2` = `test`.`t1`.`pk1` and `test`.`t1`.`f` <> 5 @@ -19205,13 +21012,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", "possible_keys": ["PRIMARY"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f <> 5" } @@ -19225,12 +21035,15 @@ EXPLAIN "key_length": "4", "used_key_parts": ["pk2"], "ref": ["test.t1.pk1"], - "rows": 2, + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -19241,7 +21054,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["pk2"], "ref": ["test.t1.pk1"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "using_index": true } @@ -19414,7 +21229,7 @@ GROUP BY t1.b,t2.c) dt WHERE t3.d = dt.b; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t3.d 2 100.00 +1 PRIMARY ref key0 key0 5 test.t3.d 1 100.00 2 LATERAL DERIVED t1 ref idx_b idx_b 5 test.t3.d 1 100.00 Using index; Using temporary; Using filesort 2 LATERAL DERIVED t2 ALL NULL NULL NULL NULL 5 100.00 Using join buffer (flat, BNL join) Warnings: @@ -19449,7 +21264,7 @@ left join on u.id=auditlastlogin.userid; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY u ALL NULL NULL NULL NULL 2 -1 PRIMARY ref key0 key0 5 test.u.id 2 +1 PRIMARY ref key0 key0 5 test.u.id 1 2 DERIVED au ALL NULL NULL NULL NULL 4 Using temporary; Using filesort select * from t1 as u left join @@ -19504,9 +21319,9 @@ id a explain extended select id, a from t1 where id in (select id from v1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 20 100.00 -1 PRIMARY ref key0 key0 4 test.t1.id 2 100.00 FirstMatch(t1) -3 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t1.id 1 100.00 -3 LATERAL DERIVED t2 ref ro_id ro_id 4 test.t1.id 1 100.00 Using where +1 PRIMARY ref key0 key0 4 test.t1.id 2 50.00 FirstMatch(t1) +3 DERIVED t1 ALL PRIMARY NULL NULL NULL 20 100.00 Using temporary; Using filesort +3 DERIVED t2 ref ro_id ro_id 4 test.t1.id 1 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`v1`) where `v1`.`id` = `test`.`t1`.`id` select id, a from t1 @@ -19542,11 +21357,11 @@ on (t1.id = t2.ro_id AND t2.flag = 1) group by t1.id) dt); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 20 100.00 -1 PRIMARY ref key0 key0 4 test.t1.id 2 100.00 FirstMatch(t1) -3 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t1.id 1 100.00 -3 LATERAL DERIVED t2 ref ro_id ro_id 4 test.t1.id 1 100.00 Using where +1 PRIMARY ref key1 key1 4 test.t1.id 2 50.00 FirstMatch(t1) +3 DERIVED t1 ALL PRIMARY NULL NULL NULL 20 100.00 Using temporary; Using filesort +3 DERIVED t2 ref ro_id ro_id 4 test.t1.id 1 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` semi join ((/* select#3 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`ro_id` = `test`.`t1`.`id` and `test`.`t2`.`flag` = 1) where `test`.`t1`.`id` = `test`.`t1`.`id` group by `test`.`t1`.`id`) `dt`) where `dt`.`id` = `test`.`t1`.`id` +Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` semi join ((/* select#3 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`ro_id` = `test`.`t1`.`id` and `test`.`t2`.`flag` = 1) where 1 group by `test`.`t1`.`id`) `dt`) where `dt`.`id` = `test`.`t1`.`id` drop view v1; drop table t1,t2; # @@ -19648,6 +21463,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -19655,9 +21471,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -19674,6 +21492,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -19681,9 +21500,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -19724,7 +21545,8 @@ create table t1 (id int, a int, index (a), index (id, a)) engine=myisam; insert into t1 values (17,1),(17,3010),(17,3013),(17,3053),(21,2446),(21,2467),(21,2); create table t2 (a int) engine=myisam; -insert into t2 values (1),(2),(3); +insert into t2 values (1),(2),(3),(1000),(2000),(3000); +insert into t2 select 5000 from seq_5000_to_6000; create table t3 (id int) engine=myisam; insert into t3 values (1),(2); analyze table t1,t2,t3; @@ -19746,22 +21568,25 @@ where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where 1 PRIMARY t1 ref a a 5 test.t3.id 1 +1 PRIMARY ref key0 key0 5 test.t3.id 1 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -1 PRIMARY ref key0 key0 5 test.t3.id 2 -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 -2 DERIVED cp2 range NULL a 5 NULL 8 Using index for group-by +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 1007 +2 DERIVED cp2 range NULL a 5 NULL 7 Using index for group-by explain format=json select * from t1, (select a from t1 cp2 group by a) dt, t3 where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.`id` is not null and t3.`id` is not null" } @@ -19775,10 +21600,49 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t3.id"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } }, + { + "table": { + "table_name": "", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t3.id"], + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "cp2", + "access_type": "range", + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "loops": 1, + "rows": 7, + "cost": "COST_REPLACED", + "filtered": 100, + "using_index_for_group_by": true + } + } + ] + } + } + } + }, { "table": { "table_name": "", @@ -19799,7 +21663,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", - "rows": 3, + "loops": 1, + "rows": 1007, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -19807,38 +21673,6 @@ EXPLAIN } } } - }, - { - "table": { - "table_name": "", - "access_type": "ref", - "possible_keys": ["key0"], - "key": "key0", - "key_length": "5", - "used_key_parts": ["a"], - "ref": ["test.t3.id"], - "rows": 2, - "filtered": 100, - "materialized": { - "query_block": { - "select_id": 2, - "nested_loop": [ - { - "table": { - "table_name": "cp2", - "access_type": "range", - "key": "a", - "key_length": "5", - "used_key_parts": ["a"], - "rows": 8, - "filtered": 100, - "using_index_for_group_by": true - } - } - ] - } - } - } } ] } @@ -19854,9 +21688,9 @@ where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where 1 PRIMARY t1 ref a a 5 test.t3.id 1 +1 PRIMARY ref key0 key0 5 test.t3.id 1 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -1 PRIMARY ref key0 key0 5 test.t3.id 2 -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 1007 2 LATERAL DERIVED cp2 ref a a 5 test.t1.a 1 Using where; Using index explain format=json select * from t1, (select a from t1 cp2 group by a) dt, t3 where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); @@ -19864,12 +21698,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.`id` is not null and t3.`id` is not null" } @@ -19883,10 +21720,54 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t3.id"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } }, + { + "table": { + "table_name": "", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t3.id"], + "loops": 2, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "materialized": { + "lateral": 1, + "query_block": { + "select_id": 2, + "cost": "COST_REPLACED", + "outer_ref_condition": "t1.a is not null", + "nested_loop": [ + { + "table": { + "table_name": "cp2", + "access_type": "ref", + "possible_keys": ["a"], + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t1.a"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "cp2.a = t3.`id`", + "using_index": true + } + } + ] + } + } + } + }, { "table": { "table_name": "", @@ -19907,7 +21788,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", - "rows": 3, + "loops": 1, + "rows": 1007, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -19915,43 +21798,6 @@ EXPLAIN } } } - }, - { - "table": { - "table_name": "", - "access_type": "ref", - "possible_keys": ["key0"], - "key": "key0", - "key_length": "5", - "used_key_parts": ["a"], - "ref": ["test.t3.id"], - "rows": 2, - "filtered": 100, - "materialized": { - "lateral": 1, - "query_block": { - "select_id": 2, - "outer_ref_condition": "t1.a is not null", - "nested_loop": [ - { - "table": { - "table_name": "cp2", - "access_type": "ref", - "possible_keys": ["a"], - "key": "a", - "key_length": "5", - "used_key_parts": ["a"], - "ref": ["test.t1.a"], - "rows": 1, - "filtered": 100, - "attached_condition": "cp2.a = t3.`id`", - "using_index": true - } - } - ] - } - } - } } ] } @@ -19969,7 +21815,7 @@ id a a id deallocate prepare stmt; drop table t1,t2,t3; # -# MDEV-MDEV-27132: Splittable derived with equality in WHERE +# MDEV-27132: Splittable derived with equality in WHERE # CREATE TABLE t1 ( id int PRIMARY KEY @@ -20010,6 +21856,7 @@ INSERT INTO t2(deleted, t1_id, email, reporting_person) SELECT deleted, t1_id+80000, email, reporting_person FROM t2; INSERT INTO t2(deleted, t1_id, email, reporting_person) SELECT deleted, t1_id+160000, email, reporting_person FROM t2; +insert into t2 (id,t1_id) select -seq,-seq from seq_1_to_1000; CREATE TABLE t3 ( id int PRIMARY KEY, deleted int, @@ -20062,8 +21909,8 @@ WHERE t1.id BETWEEN 200 AND 100000; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 range t1_id t1_id 5 NULL 47 Using where; Using index 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.t1_id 1 Using index -1 PRIMARY ref key0 key0 5 test.t3.t1_id 2 -2 LATERAL DERIVED t2 ref t1_id t1_id 5 test.t1.id 3 Using index condition; Using where +1 PRIMARY ref key0 key0 5 test.t3.t1_id 1 +2 LATERAL DERIVED t2 ref t1_id t1_id 5 test.t1.id 1 Using index condition; Using where EXPLAIN FORMAT=JSON SELECT t1.id FROM t1 JOIN t3 @@ -20075,6 +21922,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -20084,7 +21932,9 @@ EXPLAIN "key": "t1_id", "key_length": "5", "used_key_parts": ["t1_id"], + "loops": 1, "rows": 47, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.t1_id between 200 and 100000 and t3.t1_id is not null", "using_index": true @@ -20099,7 +21949,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["id"], "ref": ["test.t3.t1_id"], + "loops": 47, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "using_index": true } @@ -20113,12 +21965,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["t1_id"], "ref": ["test.t3.t1_id"], - "rows": 2, + "loops": 47, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -20129,8 +21984,10 @@ EXPLAIN "key_length": "5", "used_key_parts": ["t1_id"], "ref": ["test.t1.id"], - "rows": 3, - "filtered": 59.09090805, + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 34.55045319, "index_condition": "t2.t1_id between 200 and 100000 and t2.t1_id = t3.t1_id", "attached_condition": "t2.reporting_person = 1" } @@ -20152,6 +22009,18 @@ JOIN (SELECT t1_id FROM t2 WHERE reporting_person = 1 GROUP BY t1_id) tx ON tx.t1_id = t1.id WHERE t1.id BETWEEN 200 AND 100000; id +EXPLAIN SELECT t1.id +FROM t1 +JOIN t3 +ON t3.t1_id = t1.id +JOIN (SELECT t1_id FROM t2 WHERE reporting_person = 1 GROUP BY t1_id) tx +ON tx.t1_id = t1.id +WHERE t1.id BETWEEN 200 AND 100000; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 range t1_id t1_id 5 NULL 47 Using where; Using index +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.t1_id 1 Using index +1 PRIMARY ref key0 key0 5 test.t3.t1_id 10 +2 DERIVED t2 ALL t1_id NULL NULL NULL 2408 Using where; Using temporary; Using filesort set optimizer_switch='split_materialized=default'; DROP TABLE t1,t2,t3; # @@ -20274,8 +22143,8 @@ ON from_agg_items.charge_id = charges.id AND from_agg_items.ledger_id = charges.from_ledger_id WHERE charges.to_ledger_id = 2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY charges ALL PRIMARY,fk_charge_from_ledger,fk_charge_to_ledger NULL NULL NULL 20 Using where -1 PRIMARY ref key0 key0 17 test.charges.from_ledger_id,test.charges.id 2 +1 PRIMARY charges ref PRIMARY,fk_charge_from_ledger,fk_charge_to_ledger fk_charge_to_ledger 8 const 8 +1 PRIMARY ref key0 key0 17 test.charges.from_ledger_id,test.charges.id 1 2 LATERAL DERIVED transaction_items ref fk_items_transaction,fk_items_charge fk_items_charge 9 test.charges.id 2 2 LATERAL DERIVED transactions eq_ref PRIMARY,fk_transactions_ledger PRIMARY 8 test.transaction_items.transaction_id 1 Using where EXPLAIN FORMAT=JSON SELECT @@ -20300,19 +22169,25 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "charges", - "access_type": "ALL", + "access_type": "ref", "possible_keys": [ "PRIMARY", "fk_charge_from_ledger", "fk_charge_to_ledger" ], - "rows": 20, - "filtered": 40, - "attached_condition": "charges.to_ledger_id = 2" + "key": "fk_charge_to_ledger", + "key_length": "8", + "used_key_parts": ["to_ledger_id"], + "ref": ["const"], + "loops": 1, + "rows": 8, + "cost": "COST_REPLACED", + "filtered": 100 } }, { @@ -20324,12 +22199,15 @@ EXPLAIN "key_length": "17", "used_key_parts": ["ledger_id", "charge_id"], "ref": ["test.charges.from_ledger_id", "test.charges.id"], - "rows": 2, + "loops": 8, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -20340,7 +22218,9 @@ EXPLAIN "key_length": "9", "used_key_parts": ["charge_id"], "ref": ["test.charges.id"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -20353,7 +22233,9 @@ EXPLAIN "key_length": "8", "used_key_parts": ["id"], "ref": ["test.transaction_items.transaction_id"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "transactions.ledger_id = charges.from_ledger_id" } @@ -20413,7 +22295,7 @@ ON from_agg_items.charge_id = charges.id AND from_agg_items.ledger_id = charges.from_ledger_id WHERE charges.to_ledger_id = 2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY charges ALL PRIMARY,fk_charge_from_ledger,fk_charge_to_ledger NULL NULL NULL 20 Using where +1 PRIMARY charges ref PRIMARY,fk_charge_from_ledger,fk_charge_to_ledger fk_charge_to_ledger 8 const 8 1 PRIMARY ref key0 key0 17 test.charges.from_ledger_id,test.charges.id 4 2 DERIVED transaction_items ALL fk_items_transaction NULL NULL NULL 40 Using temporary; Using filesort 2 DERIVED transactions eq_ref PRIMARY PRIMARY 8 test.transaction_items.transaction_id 1 @@ -20468,8 +22350,8 @@ ON from_agg_items.charge_id = charges.id AND from_agg_items.ledger_id = charges.from_ledger_id WHERE charges.to_ledger_id = 2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY charges ALL fk_charge_to_ledger NULL NULL NULL 20 Using where -1 PRIMARY ref key0 key0 18 test.charges.from_ledger_id,test.charges.id 2 +1 PRIMARY charges ref fk_charge_to_ledger fk_charge_to_ledger 8 const 10 +1 PRIMARY ref key0 key0 18 test.charges.from_ledger_id,test.charges.id 1 2 LATERAL DERIVED transaction_items ref fk_items_transaction,fk_items_charge fk_items_charge 9 test.charges.id 2 2 LATERAL DERIVED transactions eq_ref PRIMARY,fk_transactions_ledger PRIMARY 8 test.transaction_items.transaction_id 1 Using where EXPLAIN FORMAT=JSON SELECT @@ -20494,15 +22376,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "charges", - "access_type": "ALL", + "access_type": "ref", "possible_keys": ["fk_charge_to_ledger"], - "rows": 20, - "filtered": 50, - "attached_condition": "charges.to_ledger_id = 2" + "key": "fk_charge_to_ledger", + "key_length": "8", + "used_key_parts": ["to_ledger_id"], + "ref": ["const"], + "loops": 1, + "rows": 10, + "cost": "COST_REPLACED", + "filtered": 100 } }, { @@ -20514,12 +22402,15 @@ EXPLAIN "key_length": "18", "used_key_parts": ["ledger_id", "charge_id"], "ref": ["test.charges.from_ledger_id", "test.charges.id"], - "rows": 2, + "loops": 10, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "lateral": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -20530,7 +22421,9 @@ EXPLAIN "key_length": "9", "used_key_parts": ["charge_id"], "ref": ["test.charges.id"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -20543,7 +22436,9 @@ EXPLAIN "key_length": "8", "used_key_parts": ["id"], "ref": ["test.transaction_items.transaction_id"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "transactions.ledger_id = charges.from_ledger_id" } @@ -20605,7 +22500,7 @@ ON from_agg_items.charge_id = charges.id AND from_agg_items.ledger_id = charges.from_ledger_id WHERE charges.to_ledger_id = 2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY charges ALL fk_charge_to_ledger NULL NULL NULL 20 Using where +1 PRIMARY charges ref fk_charge_to_ledger fk_charge_to_ledger 8 const 10 1 PRIMARY ref key0 key0 18 test.charges.from_ledger_id,test.charges.id 4 2 DERIVED transaction_items ALL fk_items_transaction NULL NULL NULL 40 Using temporary; Using filesort 2 DERIVED transactions eq_ref PRIMARY PRIMARY 8 test.transaction_items.transaction_id 1 diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index 39e82210e4c..2f2e72fb09f 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -112,6 +112,7 @@ let $query= select * from v1,t2 where (v1.max_c>214) and (t2.a>v1.a); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -122,6 +123,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # extracted or formula : pushing into HAVING @@ -131,6 +133,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -140,6 +143,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # conjunctive subformula : pushing into WHERE @@ -147,12 +151,14 @@ let $query= select * from v1,t2 where (v1.a>6) and (t2.b>v1.b); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= select * from v2,t2 where (v2.b>25) and (t2.a400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a150) and (v1.max_c=t2.c); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # extracted and formula : pushing into WHERE @@ -296,6 +319,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -303,6 +327,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -311,6 +336,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # extracted and formula : pushing into WHERE using equalities @@ -321,6 +347,7 @@ select * from v_decimal as v,t2_decimal as t where eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # extracted or formula : pushing into HAVING using equalities @@ -330,6 +357,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # conjunctive subformulas : pushing into WHERE and HAVING using equalities @@ -339,6 +367,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # conjunctive subformulas : pushing into WHERE and HAVING @@ -351,6 +380,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # conjunctive subformulas : pushing into WHERE and HAVING @@ -360,6 +390,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # conjunctive subformula : pushing into WHERE @@ -371,6 +402,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # conjunctive subformula : pushing into WHERE @@ -381,6 +413,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # extracted or formula : pushing into WHERE @@ -392,6 +425,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -402,6 +436,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # nothing to push @@ -410,12 +445,14 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -424,6 +461,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -431,6 +469,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -439,6 +478,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using several derived tables : nothing to push @@ -447,6 +487,7 @@ let $query= select * from v1,v2,t2 where eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -455,6 +496,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -463,6 +505,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using several derived tables : pushing in all tables @@ -475,6 +518,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using several derived tables : pushing only in one table @@ -486,6 +530,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using several derived tables : pushing only in one table @@ -497,6 +542,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # extracted or formula : pushing into WHERE @@ -508,6 +554,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using several derived tables : pushing in all tables @@ -521,6 +568,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using several derived tables : pushing in all tables @@ -535,6 +583,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using several derived tables : pushing in all tables @@ -553,6 +602,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # extracted or formula : pushing into HAVING @@ -565,6 +615,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # extracted and formula : pushing into WHERE @@ -577,6 +628,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using query with union @@ -589,6 +641,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using query with union @@ -602,6 +655,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using query with union @@ -616,6 +670,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using query with union @@ -634,6 +689,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union @@ -642,6 +698,7 @@ let $query= select * from v_union,t2 where (v_union.a<3) and (v_union.c>100); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union @@ -653,6 +710,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union @@ -665,6 +723,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= @@ -673,6 +732,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union @@ -686,6 +746,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union @@ -698,6 +759,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union of selects without aggregation @@ -707,6 +769,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union of selects without aggregation @@ -716,6 +779,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union of selects without aggregation @@ -726,6 +790,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union of @@ -736,6 +801,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using derived table with union of @@ -750,6 +816,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded derived table : pushing the same conditions @@ -762,6 +829,7 @@ select * from v4,v1 where eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : nothing to push @@ -773,6 +841,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : pushing different conditions @@ -786,6 +855,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : pushing different conditions @@ -798,6 +868,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : pushing different conditions @@ -810,6 +881,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : pushing different conditions @@ -823,6 +895,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : pushing the same conditions @@ -836,6 +909,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : pushing the same conditions @@ -849,6 +923,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : pushing the same conditions @@ -863,6 +938,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using embedded view : pushing the same conditions @@ -875,6 +951,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1,v2,v3,v4; @@ -982,6 +1059,7 @@ SELECT * FROM t1 WHERE a IN ( ) ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE a IN ( SELECT b FROM v2 WHERE b < a OR b IN ( @@ -1004,6 +1082,7 @@ SELECT * FROM t1 WHERE a IN ( eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; DROP VIEW v2,v3,v4; @@ -1026,6 +1105,7 @@ SELECT * FROM ( SELECT * FROM t1 WHERE EXISTS ( SELECT * FROM v2 WHERE b = a ) ) AS sq; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT * FROM t1 @@ -1051,6 +1131,7 @@ SELECT * FROM t1 LEFT JOIN t2 ON a = b WHERE b IS NULL; SELECT * FROM t1 LEFT JOIN v2 ON a = b WHERE b IS NULL; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM t1 LEFT JOIN v2 ON a = b WHERE b IS NULL; @@ -1065,6 +1146,7 @@ CREATE TABLE t1 (i INT); CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; INSERT INTO t1 VALUES (1),(2); --enable_prepare_warnings +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM v1 WHERE i <= ANY ( SELECT 3 ); --disable_prepare_warnings @@ -1092,12 +1174,14 @@ CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2; SELECT * FROM v1 AS sq WHERE b IN ( SELECT pk2 FROM v2 WHERE c > sq.b ) OR b = 100; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM v1 AS sq WHERE b IN ( SELECT pk2 FROM v2 WHERE c > sq.b ) OR b = 100; SELECT * FROM ( SELECT * FROM t1 ) AS sq WHERE b IN ( SELECT pk2 FROM v2 WHERE c > sq.b ) OR b = 100; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT * FROM t1 ) AS sq WHERE b IN ( SELECT pk2 FROM v2 WHERE c > sq.b ) OR b = 100; @@ -1117,6 +1201,7 @@ INSERT INTO t2 VALUES (50); CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; SELECT ( SELECT COUNT(*) FROM v1 WHERE a = t2.b ) AS f FROM t2 GROUP BY f; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT ( SELECT COUNT(*) FROM v1 WHERE a = t2.b ) AS f FROM t2 GROUP BY f; @@ -1124,6 +1209,7 @@ CREATE TABLE t3 (a INT, b INT) ENGINE=MYISAM; INSERT INTO t3 VALUES (1,10),(3,11),(2,10),(2,20),(3,21); CREATE VIEW v2 AS SELECT a, sum(b) AS s FROM t3 GROUP BY a ; SELECT ( SELECT COUNT(*) FROM v2 WHERE s < t2.b ) AS f FROM t2 GROUP BY f; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT ( SELECT COUNT(*) FROM v2 WHERE s < t2.b ) AS f FROM t2 GROUP BY f; @@ -1145,6 +1231,7 @@ INSERT INTO t2 VALUES (5),(6); SELECT a, GROUP_CONCAT(b) FROM v1 WHERE b IN ( SELECT COUNT(c) FROM t2 ) GROUP BY a; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT a, GROUP_CONCAT(b) FROM v1 WHERE b IN ( SELECT COUNT(c) FROM t2 ) GROUP BY a; @@ -1163,6 +1250,7 @@ INSERT INTO t VALUES (1,1),(3,2); SELECT * FROM v AS v1, v AS v2 WHERE v2.pk > v1.f AND v1.f IN ( SELECT COUNT(pk) FROM t ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM v AS v1, v AS v2 WHERE v2.pk > v1.f AND v1.f IN ( SELECT COUNT(pk) FROM t ); @@ -1182,6 +1270,7 @@ INSERT INTO t2 VALUES (3),(4); SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); @@ -1200,6 +1289,7 @@ INSERT INTO t2 VALUES (3.2),(2.71); SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); @@ -1214,6 +1304,7 @@ INSERT INTO t2 VALUES (3.21),(4.55); SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); @@ -1228,6 +1319,7 @@ INSERT INTO t2 VALUES ('bbb'),('aa'); SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); @@ -1244,6 +1336,7 @@ INSERT INTO t2 VALUES SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); @@ -1258,6 +1351,7 @@ INSERT INTO t2 VALUES ('2007-05-28'), ('2010-08-25'); SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); @@ -1272,6 +1366,7 @@ INSERT INTO t2 VALUES ('10:00:02'), ('11:00:10'); SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq WHERE i IN ( SELECT MIN(j) FROM t2 ); @@ -1288,6 +1383,7 @@ CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; INSERT INTO t1 VALUES (2), (1); SELECT * FROM v1 WHERE NULLIF(1, i); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM v1 WHERE NULLIF(1, i); @@ -1306,6 +1402,7 @@ CREATE TABLE t2 (c VARCHAR(3)); INSERT INTO t2 VALUES ('foo'),('xyz'); SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 ); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 ); @@ -1340,7 +1437,9 @@ PREPARE stmt1 FROM PREPARE stmt2 FROM "EXPLAIN FORMAT=JSON SELECT * FROM v1 WHERE 1 IN (SELECT a FROM t2) OR c = 'foo'"; +--source include/explain-no-costs.inc EXECUTE stmt1; +--source include/explain-no-costs.inc EXECUTE stmt2; INSERT INTO t2 SELECT a+1 FROM t2; INSERT INTO t2 SELECT a+1 FROM t2; @@ -1348,7 +1447,9 @@ INSERT INTO t2 SELECT a+1 FROM t2; INSERT INTO t2 SELECT a+1 FROM t2; INSERT INTO t2 SELECT a+1 FROM t2; INSERT INTO t2 SELECT a+1 FROM t2; +--source include/explain-no-costs.inc EXECUTE stmt1; +--source include/explain-no-costs.inc EXECUTE stmt2; DEALLOCATE PREPARE stmt1; # the result here will change after the merge with the fix for mdev-11859 @@ -1485,6 +1586,7 @@ from ( select t1.a, v1.b, v1.s from t1, v1 where t1.a = v1.b ) as t where b > 2; eval $q1; +--source include/explain-no-costs.inc eval explain format=json $q1; let $q2= @@ -1493,6 +1595,7 @@ from ( select t1.a, v1.b, v1.s from t1, v1 where t1.a = v1.b ) as t where a > 2; eval $q2; +--source include/explain-no-costs.inc eval explain format=json $q2; let $q3= @@ -1501,6 +1604,7 @@ from ( select t1.a, v2.b, v2.c from t1, v2 where t1.a = v2.b ) as t where a > 2; eval $q3; +--source include/explain-no-costs.inc eval explain format=json $q3; let $q4= @@ -1509,6 +1613,7 @@ from ( select t1.a, v3.b, v3.m from t1, v3 where t1.a = v3.m ) as t where a > 2; eval $q4; +--source include/explain-no-costs.inc eval explain format=json $q4; drop view v1,v2,v3; @@ -1526,6 +1631,7 @@ let $q= SELECT * FROM ( SELECT * FROM v1 ) AS sq WHERE f > 0; eval $q; +--source include/explain-no-costs.inc eval explain format=json $q; DROP VIEW v1; @@ -1548,6 +1654,7 @@ SELECT * FROM t1, ( SELECT * FROM v2 ) AS sq WHERE i1 = 1 AND ( i1 = i2 OR i1 = 2 ); eval $q; +--source include/explain-no-costs.inc eval explain format=json $q; DROP VIEW v2; @@ -1566,6 +1673,7 @@ from ( select distinct regexp_substr(t1.a,'^[A-Za-z]+') as f from t1) as t where t.f = 'a' or t.f = 'b'; eval $q; +--source include/explain-no-costs.inc eval explain format=json $q; drop table t1; @@ -1589,6 +1697,7 @@ SELECT * FROM t1 WHERE (vc.ct>0); eval $q; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q; DROP TABLE t1,t2; @@ -1619,6 +1728,7 @@ WHERE (v1.a=1) AND (v1.b=v1.a) AND (v1.a=t2.x) AND (v1.max_c>30); eval $query; eval EXPLAIN $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; let $query= @@ -1634,6 +1744,7 @@ WHERE (v1.a=1) AND (v1.b=v1.a) AND (v1.b=v1.d) AND (v1.a=t2.x) AND (v1.max_c>30); eval $query; eval EXPLAIN $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; DROP TABLE t1,t2; @@ -1676,6 +1787,7 @@ WHERE (t1.a,t1.b) IN ; eval $query; eval EXPLAIN $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; let $query= @@ -1694,6 +1806,7 @@ WHERE (t1.a,t1.b) IN ; eval $query; eval EXPLAIN $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; let $query= @@ -1712,6 +1825,7 @@ WHERE (t1.a,t1.b) IN ; eval $query; eval EXPLAIN $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; let $query= @@ -1730,6 +1844,7 @@ WHERE (t1.a,t1.b) IN ; eval $query; eval EXPLAIN $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; DROP TABLE t1,t2; @@ -1768,6 +1883,7 @@ SELECT * FROM ) dt WHERE (dt.a=2); eval $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; let $query= @@ -1780,6 +1896,7 @@ SELECT * FROM ) dt WHERE (dt.a>1); eval $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; let $query= @@ -1791,6 +1908,7 @@ SELECT * FROM ) dt WHERE (dt.a='ab'); eval $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; let $query= @@ -1802,6 +1920,7 @@ SELECT * FROM ) dt WHERE (dt.a=1); eval $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; DROP TABLE t1; @@ -1830,6 +1949,7 @@ JOIN ) AS dt2 ON dt1.a = dt2.a; eval $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; let $query= @@ -1841,6 +1961,7 @@ SELECT * FROM ) AS dt, t1 WHERE dt.a=t1.a AND dt.a IN (1,t1.a); eval $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; DROP TABLE t1; @@ -1943,6 +2064,7 @@ let $q1= INSERT INTO t3 SELECT * FROM (SELECT a, count(*) as c FROM t1 GROUP BY a) t WHERE a<=2; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q1; eval $q1; @@ -1952,6 +2074,7 @@ let $q2= UPDATE t2, (SELECT a, count(*) as c FROM t1 GROUP BY a) t SET t2.a=t.c+10 WHERE t2.a= t.c and t.a>=3; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q2; eval $q2; @@ -1961,6 +2084,7 @@ let $q3= DELETE t2 FROM t2, (SELECT a, count(*) as c FROM t1 GROUP BY a) t WHERE t2.a= t.c+9 and t.a=2; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q3; eval $q3; @@ -1986,6 +2110,7 @@ FROM ) AS tab1 WHERE (tab1.max_a=1); EVAL $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; LET $query= @@ -1998,6 +2123,7 @@ FROM ) AS tab1 WHERE (tab1.max_a=1); EVAL $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; LET $query= @@ -2010,6 +2136,7 @@ FROM ) AS tab1 WHERE (tab1.max_a=1); EVAL $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; LET $query= @@ -2022,6 +2149,7 @@ FROM ) AS tab1 WHERE (tab1.max_a=1); EVAL $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; DROP TABLE t1; @@ -2061,6 +2189,7 @@ SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ) AS t WHERE f IS NOT NULL; eval $q1; eval EXPLAIN $q1; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q1; SELECT * FROM t1; @@ -2073,6 +2202,7 @@ SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ON v1.f=t1.f) AS t WHERE f IS NOT NULL; eval $q2; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q2; SELECT * FROM t1; @@ -2093,6 +2223,7 @@ CREATE VIEW v1 AS SELECT f2 FROM ( SELECT f2 FROM t1 ) AS t; let $q1 = UPDATE v1, t1 SET t1.f1 = 'z' WHERE v1.f2 < 2 AND t1.f2 = v1.f2; eval $q1; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q1; SELECT * FROM t1; @@ -2101,6 +2232,7 @@ CREATE VIEW v2 AS SELECT f2 FROM ( SELECT DISTINCT f2 FROM t1 ) AS t; let $q2 = SELECT * FROM v2, t1 WHERE v2.f2 < 2 AND t1.f2 = v2.f2; eval $q2; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q2; DROP VIEW v1,v2; @@ -2136,6 +2268,7 @@ CREATE TABLE t1 (a INT, b INT); CREATE VIEW v1 AS SELECT a, MAX(b) FROM t1 GROUP BY a; SELECT * FROM (SELECT 1 FROM v1 UNION (SELECT 1 FROM v1 WHERE @a := uuid())) dt; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM (SELECT 1 FROM v1 UNION (SELECT 1 FROM v1 WHERE @a := uuid())) dt; @@ -2280,6 +2413,7 @@ select col2, col1 from v2; explain select * from v3 where col1=123; --echo # This must use ref accesses for reading table t1, not full scans: +--source include/explain-no-costs.inc explain format=json select * from v3 where col1=123 and col2=321; @@ -2303,6 +2437,7 @@ select a, f1(a), sum(b) from t1 group by a, f1(a); --echo # "a > 1" will be pushed all the way to the table scan on t1 --echo # "a2>123" will be pushed into HAVING (as it refers to an SP call which --echo # prevents pushing it to the WHERE) +--source include/explain-no-costs.inc explain format=json select * from v2 where (s+1) > 10 AND a > 1 and a2>123; @@ -2315,6 +2450,7 @@ insert into t4 select a,a,a from t1; --echo # The subquery must be materialized and must have --echo # "attached_condition": "t1.a + 1 > 10", --echo # "having_condition": "`f1(a)` > 1 and `sum(b)` > 123", +--source include/explain-no-costs.inc explain format=json select * from t4 @@ -2359,6 +2495,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using intersect in view definition @@ -2368,6 +2505,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a=8); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using intersect in view definition @@ -2376,6 +2514,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (t2.a=8); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using intersect in view definition @@ -2384,6 +2523,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.c>200); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using intersect in view definition @@ -2393,6 +2533,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>110); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using intersect in view definition @@ -2402,6 +2543,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using intersect in view definition @@ -2412,6 +2554,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using intersect in view definition @@ -2425,6 +2568,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using intersect in view definition @@ -2456,6 +2600,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2473,6 +2618,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using except in view definition @@ -2482,6 +2628,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a=6); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using except in view definition @@ -2490,6 +2637,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (t2.a=6); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using except in view definition @@ -2498,6 +2646,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.c>500); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using except in view definition @@ -2507,6 +2656,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<5) and (v1.c>500); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using except in view definition @@ -2516,6 +2666,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using except in view definition @@ -2526,6 +2677,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using except in view definition @@ -2540,6 +2692,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --echo # using except in view definition @@ -2571,6 +2724,7 @@ let $query= eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2591,6 +2745,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2611,6 +2766,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2631,6 +2787,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>5) and (v1.c>200); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2651,6 +2808,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<200); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2671,6 +2829,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<150); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2691,6 +2850,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2714,6 +2874,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.c<130); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2736,6 +2897,7 @@ let $query= select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1,v2; @@ -2758,6 +2920,7 @@ let $query= select * from v2,t2 where (v2.a=t2.a) and (v2.a>4) and (v2.c<150); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1,v2; @@ -2776,6 +2939,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>4) and (v1.b>12) and eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2794,6 +2958,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a<2) and (v1.b<30) and eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2814,6 +2979,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and ((v1.a<2) or (v1.a<5)) and eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2835,6 +3001,7 @@ let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.a>1) and (v1.b > 12) a eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2858,6 +3025,7 @@ let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<5); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2876,6 +3044,7 @@ let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<4); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2894,6 +3063,7 @@ let $query= select * from v1,t2 where (v1.b=t2.b) and (v1.a<3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; drop view v1; @@ -2930,6 +3100,7 @@ eval $no_pushdown $q1; --sorted_result eval $q1; eval explain $q1; +--source include/explain-no-costs.inc eval explain format=json $q1; let $q2= @@ -2946,6 +3117,7 @@ eval $no_pushdown $q2; --sorted_result eval $q2; eval explain $q2; +--source include/explain-no-costs.inc eval explain format=json $q2; let $q3= @@ -2956,6 +3128,7 @@ from (select a, c, sum(b) over (partition by a,c) as s from t2) as t, t1 eval $no_pushdown $q3; eval $q3; eval explain $q3; +--source include/explain-no-costs.inc eval explain format=json $q3; let $q4= @@ -2974,6 +3147,7 @@ eval $no_pushdown $q4; --sorted_result eval $q4; eval explain $q4; +--source include/explain-no-costs.inc eval explain format=json $q4; let $q5= @@ -2988,6 +3162,7 @@ eval $no_pushdown $q5; --sorted_result eval $q5; eval explain $q5; +--source include/explain-no-costs.inc eval explain format=json $q5; let $q6= @@ -3002,6 +3177,7 @@ eval $no_pushdown $q6; --sorted_result eval $q6; eval explain $q6; +--source include/explain-no-costs.inc eval explain format=json $q6; let $q7= @@ -3016,6 +3192,7 @@ eval $no_pushdown $q7; --sorted_result eval $q7; eval explain $q7; +--source include/explain-no-costs.inc eval explain format=json $q7; drop table t1,t2; @@ -3063,6 +3240,7 @@ where t1.b < 3; eval $no_splitting $q1; eval $q1; eval explain extended $q1; +--source include/explain-no-costs.inc eval explain format=json $q1; eval prepare stmt from "$q1"; execute stmt; @@ -3079,6 +3257,7 @@ where t1.b <= 5; eval $no_splitting $q10; eval $q10; eval explain extended $q10; +--source include/explain-no-costs.inc eval explain format=json $q10; eval prepare stmt from "$q10"; execute stmt; @@ -3096,6 +3275,7 @@ from t1 left join eval $no_splitting $q2; eval $q2; eval explain extended $q2; +--source include/explain-no-costs.inc eval explain format=json $q2; create table t3 (a int, b int, c char(127), index idx_b(b)) engine=myisam; @@ -3125,6 +3305,7 @@ where t3.b > 15; eval $no_splitting $q3; eval $q3; eval explain extended $q3; +--source include/explain-no-costs.inc eval explain format=json $q3; let $q30= @@ -3137,6 +3318,7 @@ where t3.b <= 15; eval $no_splitting $q30; eval $q30; eval explain extended $q30; +--source include/explain-no-costs.inc eval explain format=json $q30; let $q4= @@ -3149,6 +3331,7 @@ where t3.b > 15; eval $no_splitting $q4; eval $q4; eval explain extended $q4; +--source include/explain-no-costs.inc eval explain format=json $q4; let $q40= @@ -3161,6 +3344,7 @@ where t3.b <= 15; eval $no_splitting $q40; eval $q40; eval explain extended $q40; +--source include/explain-no-costs.inc eval explain format=json $q40; drop index idx_a on t2; @@ -3184,6 +3368,7 @@ eval $no_splitting $q5; --sorted_result eval $q5; eval explain extended $q5; +--source include/explain-no-costs.inc eval explain format=json $q5; let $q50= @@ -3194,6 +3379,7 @@ where t2.b < 40 and t2.a=t3.a and t3.c=t.c; eval $no_splitting $q50; eval $q50; eval explain extended $q50; +--source include/explain-no-costs.inc eval explain format=json $q50; let $q6= @@ -3206,6 +3392,7 @@ eval $no_splitting $q6; --sorted_result eval $q6; eval explain extended $q6; +--source include/explain-no-costs.inc eval explain format=json $q6; let $q60= @@ -3218,6 +3405,7 @@ eval $no_splitting $q60; --sorted_result eval $q60; eval explain extended $q60; +--source include/explain-no-costs.inc eval explain format=json $q60; drop table t1,t2,t3,t4; @@ -3254,6 +3442,7 @@ SELECT * FROM t4 WHERE c IN ( SELECT c FROM v1 ) and a < 2; eval $no_splitting $q1; eval $q1; eval explain extended $q1; +--source include/explain-no-costs.inc eval explain format=json $q1; DROP VIEW v1; @@ -3324,7 +3513,7 @@ CREATE TABLE t1 (pk1 INT PRIMARY KEY, f INT) ENGINE=Aria; INSERT INTO t1 VALUES (1,0),(2,0); CREATE TABLE t2 (pk2 INT PRIMARY KEY) ENGINE=Aria; -INSERT INTO t2 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (1),(2),(3),(11),(12),(13); CREATE VIEW v2 AS SELECT pk2, COUNT(*) AS cnt FROM t2 GROUP BY pk2; @@ -3333,6 +3522,7 @@ SELECT * FROM t1 INNER JOIN v2 ON pk1 = pk2 WHERE f <> 5; eval $q; eval EXPLAIN EXTENDED $q; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q; DROP VIEW v2; @@ -3601,7 +3791,8 @@ insert into t1 values (17,1),(17,3010),(17,3013),(17,3053),(21,2446),(21,2467),(21,2); create table t2 (a int) engine=myisam; -insert into t2 values (1),(2),(3); +insert into t2 values (1),(2),(3),(1000),(2000),(3000); +insert into t2 select 5000 from seq_5000_to_6000; create table t3 (id int) engine=myisam; insert into t3 values (1),(2); @@ -3615,11 +3806,13 @@ select * from t1, (select a from t1 cp2 group by a) dt, t3 set optimizer_switch="split_materialized=off"; eval $q; eval explain $q; +--source include/explain-no-costs.inc eval explain format=json $q; set optimizer_switch="split_materialized=default"; eval $q; eval explain $q; +--source include/explain-no-costs.inc eval explain format=json $q; eval prepare stmt from "$q"; @@ -3630,7 +3823,7 @@ deallocate prepare stmt; drop table t1,t2,t3; --echo # ---echo # MDEV-MDEV-27132: Splittable derived with equality in WHERE +--echo # MDEV-27132: Splittable derived with equality in WHERE --echo # CREATE TABLE t1 ( @@ -3677,6 +3870,9 @@ INSERT INTO t2(deleted, t1_id, email, reporting_person) INSERT INTO t2(deleted, t1_id, email, reporting_person) SELECT deleted, t1_id+160000, email, reporting_person FROM t2; +insert into t2 (id,t1_id) select -seq,-seq from seq_1_to_1000; + + CREATE TABLE t3 ( id int PRIMARY KEY, deleted int, @@ -3719,11 +3915,13 @@ set optimizer_switch='split_materialized=on'; eval $q; eval EXPLAIN $q; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q; set optimizer_switch='split_materialized=off'; eval $q; +eval EXPLAIN $q; set optimizer_switch='split_materialized=default'; @@ -3826,6 +4024,7 @@ WHERE charges.to_ledger_id = 2; set optimizer_switch='split_materialized=on'; eval $q; eval EXPLAIN $q; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q; set optimizer_switch='split_materialized=off'; @@ -3858,6 +4057,7 @@ WHERE charges.to_ledger_id = 2; set optimizer_switch='split_materialized=on'; eval $q1; eval EXPLAIN $q1; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q1; set optimizer_switch='split_materialized=off'; diff --git a/mysql-test/main/derived_opt.result b/mysql-test/main/derived_opt.result index cf0c1cb617f..53ee25963bb 100644 --- a/mysql-test/main/derived_opt.result +++ b/mysql-test/main/derived_opt.result @@ -92,13 +92,13 @@ pla_id test explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 -1 PRIMARY ref key0 key0 7 test.m2.matintnum 2 +1 PRIMARY ref key0 key0 7 test.m2.matintnum 1 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 -1 PRIMARY ref key0 key0 7 test.m2.matintnum 2 +1 PRIMARY ref key0 key0 7 test.m2.matintnum 1 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 drop table t1,t2; @@ -323,10 +323,9 @@ JOIN t1 AS tc ON (tb.pk = tc.pk) JOIN t4 AS td ON tc.a = td.a) tu) limit 10; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL # +1 PRIMARY ALL NULL NULL NULL NULL # 1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 tu.pk # Using index 1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 tu.pk # Using index -2 MATERIALIZED ALL NULL NULL NULL NULL # 3 DERIVED td system PRIMARY NULL NULL NULL # Using temporary 3 DERIVED tc ref PRIMARY,a a 3 const # 3 DERIVED ta eq_ref PRIMARY PRIMARY 4 test.tc.pk # Using index @@ -535,7 +534,7 @@ ON t2.id=t.id WHERE t2.id < 3; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition -1 PRIMARY ref key0 key0 5 test.t2.id 2 +1 PRIMARY ref key0 key0 5 test.t2.id 1 2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort set join_cache_level=default; set optimizer_switch= @save_optimizer_switch; diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 74876836a53..9569b85c234 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -20,7 +20,7 @@ EXPLAIN SELECT t1.n1 FROM t1, (SELECT n1, n2 FROM t1 WHERE c1 = 'a' GROUP BY n1) WHERE t.n1 = t1.n1 AND t.n2 = t1.n2 AND c1 = 'a' GROUP BY n1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ref c1,n1_c1_n2 c1 1 const 2 Using index condition; Using where; Using temporary; Using filesort -1 PRIMARY ref key0 key0 8 test.t1.n1,test.t1.n2 2 +1 PRIMARY ref key0 key0 8 test.t1.n1,test.t1.n2 1 2 LATERAL DERIVED t1 ref c1,n1_c1_n2 n1_c1_n2 4 test.t1.n1 1 Using where; Using index SELECT t1.n1 FROM t1, (SELECT n1, n2 FROM t1 WHERE c1 = 'a' GROUP BY n1) as t WHERE t.n1 = t1.n1 AND t.n2 = t1.n2 AND c1 = 'a' GROUP BY n1; @@ -49,7 +49,7 @@ t2 WHERE t2.id2=t.id2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where -1 PRIMARY ref key0 key0 5 test.t2.id2 2 +1 PRIMARY ref key0 key0 5 test.t2.id2 1 2 DERIVED t3 ALL NULL NULL NULL NULL 1 Using where; Using temporary; Using filesort 2 DERIVED t1 eq_ref PRIMARY,id2 PRIMARY 4 test.t3.i3 1 2 DERIVED t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) @@ -99,7 +99,7 @@ ON t2.id=t.id WHERE t2.id < 3; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 Using where -1 PRIMARY ref key0 key0 5 test.t2.id 2 +1 PRIMARY ref key0 key0 5 test.t2.id 1 2 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t2.id 1 set join_cache_level=default; DROP TABLE t1,t2; @@ -128,8 +128,8 @@ left join (v1 join t1 as t on v1.f1=t.f1 and t.f2 = null) on t1.f1=t.f1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t const f2 NULL NULL NULL 1 Impossible ON condition -1 PRIMARY const key1 NULL NULL NULL 1 Impossible ON condition +1 PRIMARY t const f2 NULL NULL NULL 0 Impossible ON condition +1 PRIMARY const key1 NULL NULL NULL 0 Impossible ON condition 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 2 DERIVED t2 ALL PRIMARY NULL NULL NULL 3 Using temporary; Using filesort set statement optimizer_switch='split_materialized=off' for explain select t.f2 @@ -138,8 +138,8 @@ left join (v1 join t1 as t on v1.f1=t.f1 and t.f2 = null) on t1.f1=t.f1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t const f2 NULL NULL NULL 1 Impossible ON condition -1 PRIMARY const key1 NULL NULL NULL 1 Impossible ON condition +1 PRIMARY t const f2 NULL NULL NULL 0 Impossible ON condition +1 PRIMARY const key1 NULL NULL NULL 0 Impossible ON condition 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 3 DERIVED t2 index NULL PRIMARY 4 NULL 3 drop view v1; @@ -157,26 +157,26 @@ set statement optimizer_switch='split_materialized=off' for EXPLAIN SELECT * FROM t1 JOIN -(SELECT t1.a, t1.b FROM t1, t2 WHERE t1.b = t2.c GROUP BY t1.a, t1.b) as dt +(SELECT t1_inner.a, t1_inner.b FROM t1 as t1_inner, t2 as t2_inner WHERE t1_inner.b = t2_inner.c GROUP BY t1_inner.a, t1_inner.b) as dt WHERE t1.a = dt.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index a,a_2 a_2 10 NULL 6 Using where; Using index -1 PRIMARY ref key0 key0 5 test.t1.a 2 -3 DERIVED t1 index NULL a_2 10 NULL 6 Using where; Using index -3 DERIVED t2 ref c c 5 test.t1.b 1 Using index +1 PRIMARY ref key0 key0 5 test.t1.a 1 +3 DERIVED t1_inner index NULL a_2 10 NULL 6 Using where; Using index +3 DERIVED t2_inner ref c c 5 test.t1_inner.b 1 Using index set statement optimizer_switch='split_materialized=on' for EXPLAIN SELECT * FROM t1 JOIN -(SELECT t1.a, t1.b FROM t1, t2 WHERE t1.b = t2.c GROUP BY t1.a, t1.b) as dt +(SELECT t1_inner.a, t1_inner.b FROM t1 as t1_inner, t2 as t2_inner WHERE t1_inner.b = t2_inner.c GROUP BY t1_inner.a, t1_inner.b) as dt WHERE t1.a = dt.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index a,a_2 a_2 10 NULL 6 Using where; Using index -1 PRIMARY ref key0 key0 5 test.t1.a 2 -3 LATERAL DERIVED t1 ref a,a_2 a 5 test.t1.a 1 Using where; Using temporary; Using filesort -3 LATERAL DERIVED t2 ref c c 5 test.t1.b 1 Using index +1 PRIMARY ref key0 key0 5 test.t1.a 1 +3 DERIVED t1_inner index a,a_2 a_2 10 NULL 6 Using where; Using index +3 DERIVED t2_inner ref c c 5 test.t1_inner.b 1 Using index DROP TABLE t1, t2; # # Bug mdev-25714: usage non-splitting covering index is cheaper than @@ -208,8 +208,8 @@ t2 where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 -1 PRIMARY ref key1 key1 4 test.t2.id 2 -1 PRIMARY t1 ALL idx NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 PRIMARY ref key1 key1 4 test.t2.id 1 +1 PRIMARY t1 ref idx idx 4 test.t2.id 3 Using where 2 DERIVED t3 ref idx1,idx2 idx1 4 const 5 Using where; Using index select t1.id, t1.itemid, dt.id, t2.id from t1, @@ -227,8 +227,8 @@ t2 where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 -1 PRIMARY ref key1 key1 4 test.t2.id 2 -1 PRIMARY t1 ALL idx NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 PRIMARY ref key1 key1 4 test.t2.id 1 +1 PRIMARY t1 ref idx idx 4 test.t2.id 3 Using where 2 DERIVED t3 ref idx1 idx1 4 const 5 Using where; Using index select t1.id, t1.itemid, dt.id, t2.id from t1, @@ -273,7 +273,7 @@ on t3.a=t.a and t3.c=t.c where t3.b > 15; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 range idx_b idx_b 5 NULL 2 Using index condition; Using where -1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 2 +1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 1 2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 # ... and if one adds WITH ROLLUP, then LATERAL DERIVED is no longer used: explain select t3.a,t3.c,t.max,t.min diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index 1ebe27cd12c..86a2b6d73b0 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -146,7 +146,7 @@ EXPLAIN SELECT * FROM t1 JOIN - (SELECT t1.a, t1.b FROM t1, t2 WHERE t1.b = t2.c GROUP BY t1.a, t1.b) as dt + (SELECT t1_inner.a, t1_inner.b FROM t1 as t1_inner, t2 as t2_inner WHERE t1_inner.b = t2_inner.c GROUP BY t1_inner.a, t1_inner.b) as dt WHERE t1.a = dt.a; diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result index b86cd1c42cc..e7190e29f3f 100644 --- a/mysql-test/main/derived_view.result +++ b/mysql-test/main/derived_view.result @@ -214,7 +214,7 @@ explain extended select * from t1 join (select * from t2 group by f2) tt on f1=f2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.f1 2 100.00 +1 PRIMARY ref key0 key0 5 test.t1.f1 1 100.00 2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`tt`.`f2` AS `f2`,`tt`.`f22` AS `f22` from `test`.`t1` join (/* select#2 */ select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` group by `test`.`t2`.`f2`) `tt` where `tt`.`f2` = `test`.`t1`.`f1` @@ -228,7 +228,7 @@ flush status; explain select * from t1 join (select * from t2 group by f2) tt on f1=f2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where -1 PRIMARY ref key0 key0 5 test.t1.f1 2 +1 PRIMARY ref key0 key0 5 test.t1.f1 1 2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort show status like 'Handler_read%'; Variable_name Value @@ -288,7 +288,7 @@ explain showing created indexes explain extended select * from t1 join v2 on f1=f2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.f1 2 100.00 +1 PRIMARY ref key0 key0 5 test.t1.f1 1 100.00 2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`v2`.`f2` AS `f2`,`v2`.`f22` AS `f22` from `test`.`t1` join `test`.`v2` where `v2`.`f2` = `test`.`t1`.`f1` @@ -339,7 +339,7 @@ flush status; explain select * from t1 join v2 on f1=f2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where -1 PRIMARY ref key0 key0 5 test.t1.f1 2 +1 PRIMARY ref key0 key0 5 test.t1.f1 1 2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort show status like 'Handler_read%'; Variable_name Value @@ -372,7 +372,7 @@ Handler_read_rnd_next 36 explain extended select * from v1 join v4 on f1=f2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 11 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t2.f2 2 100.00 +1 PRIMARY ref key0 key0 5 test.t2.f2 1 100.00 2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`v1` join `test`.`t2` where `v1`.`f1` = `test`.`t2`.`f2` and `test`.`t2`.`f2` in (2,3) @@ -381,12 +381,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.f2 in (2,3) and t2.f2 is not null" } @@ -400,11 +403,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["f1"], "ref": ["test.t2.f2"], - "rows": 2, + "loops": 11, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.f1", "temporary_table": { @@ -413,7 +419,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f1 in (2,3)" } @@ -485,16 +493,20 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "tt.f1", "temporary_table": { @@ -503,12 +515,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tt.f1 > 2", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.f1", "temporary_table": { @@ -517,7 +532,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f1 < 7 and t1.f1 > 2" } @@ -552,7 +569,7 @@ join on x.f1 = z.f1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY ALL NULL NULL NULL NULL 11 100.00 Using where -1 PRIMARY ref key0 key0 5 tt.f1 2 100.00 +1 PRIMARY ref key0 key0 5 tt.f1 1 100.00 5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort 3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort Warnings: @@ -566,17 +583,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tt.f1 > 2 and tt.f1 > 2 and tt.f1 is not null", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.f1", "temporary_table": { @@ -585,7 +606,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f1 < 7 and t1.f1 > 2 and t1.f1 > 2" } @@ -606,11 +629,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["f1"], "ref": ["tt.f1"], - "rows": 2, + "loops": 11, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 5, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.f1", "temporary_table": { @@ -619,7 +645,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f1 < 7 and t1.f1 > 2 and t1.f1 > 2" } @@ -689,7 +717,7 @@ join on x.f1 = z.f1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY ALL NULL NULL NULL NULL 11 100.00 Using where -1 PRIMARY ref key0 key0 5 x.f1 2 100.00 +1 PRIMARY ref key0 key0 5 x.f1 1 100.00 4 DERIVED ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort 5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort 2 DERIVED ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort @@ -707,17 +735,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "x.f1 is not null", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "tt.f1", "temporary_table": { @@ -726,12 +758,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tt.f1 > 2", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.f1", "temporary_table": { @@ -740,7 +775,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f1 < 7 and t1.f1 > 2" } @@ -768,11 +805,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["f1"], "ref": ["x.f1"], - "rows": 2, + "loops": 11, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 4, + "cost": "COST_REPLACED", "filesort": { "sort_key": "tt.f1", "temporary_table": { @@ -781,12 +821,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tt.f1 > 2", "materialized": { "query_block": { "select_id": 5, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.f1", "temporary_table": { @@ -795,7 +838,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f1 < 7 and t1.f1 > 2" } @@ -853,17 +898,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.f1 < 7", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.f1", "temporary_table": { @@ -872,7 +921,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f1 < 7" } @@ -930,7 +981,7 @@ join of above two explain extended select * from v6 join v7 on f2=f1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 11 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t2.f2 2 100.00 +1 PRIMARY ref key0 key0 5 test.t2.f2 1 100.00 5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22`,`v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`t2` join `test`.`v1` where `v1`.`f1` = `test`.`t2`.`f2` and `test`.`t2`.`f2` < 7 and `test`.`t2`.`f2` in (2,3) @@ -939,12 +990,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.f2 < 7 and t2.f2 in (2,3) and t2.f2 is not null" } @@ -958,11 +1012,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["f1"], "ref": ["test.t2.f2"], - "rows": 2, + "loops": 11, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 5, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.f1", "temporary_table": { @@ -971,7 +1028,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.f1 < 7 and t1.f1 in (2,3)" } @@ -994,7 +1053,7 @@ test two keys explain select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where -1 PRIMARY ref key0 key0 5 test.t1.f1 2 +1 PRIMARY ref key0 key0 5 test.t1.f1 1 1 PRIMARY xx ALL NULL NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join) 2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1; @@ -1019,7 +1078,7 @@ EXPLAIN SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index f1 f1 5 NULL 3 Using where; Using index -1 PRIMARY ref key0 key0 5 test.t2.f1 2 +1 PRIMARY ref key0 key0 5 test.t2.f1 1 2 DERIVED t1 ALL NULL NULL NULL NULL 4 SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1; f1 f1 @@ -1216,7 +1275,7 @@ SELECT * FROM t3 WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where -2 DEPENDENT SUBQUERY ref key1 key1 5 func 2 100.00 +2 DEPENDENT SUBQUERY ref key1 key1 5 func 1 100.00 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 3 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using temporary; Using filesort Warnings: @@ -1248,9 +1307,9 @@ SELECT t.f1 AS f FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4 WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where; Using filesort -1 PRIMARY t4 ref f2 f2 4 t.f1 1 Using index -1 PRIMARY t3 ref f2 f2 4 t.f1 2 Using index +1 PRIMARY t4 index f2 f2 9 NULL 2 Using where; Using index; Using temporary; Using filesort +1 PRIMARY ref key1 key1 4 test.t4.f2 1 +1 PRIMARY t3 ref f2 f2 4 test.t4.f2 1 Using index 2 DERIVED t2 system NULL NULL NULL NULL 1 Using temporary 2 DERIVED t1 ref f2 f2 4 const 2 Using where SELECT t.f1 AS f @@ -1276,7 +1335,7 @@ EXPLAIN SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY ref key0 key0 5 test.t.a 2 +1 PRIMARY ref key0 key0 5 test.t.a 1 2 DERIVED t1 ALL NULL NULL NULL NULL 3 SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b; a b a b @@ -1582,7 +1641,7 @@ EXPLAIN SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -1 PRIMARY ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1) +1 PRIMARY ref key0 key0 10 test.t1.a,test.t1.b 1 FirstMatch(t1) 3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort SELECT * FROM v2; a b @@ -1881,14 +1940,14 @@ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM t3 t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY t unique_subquery PRIMARY,c PRIMARY 4 func 1 Using where +2 DEPENDENT SUBQUERY t index_subquery PRIMARY,c c 8 func,func 1 Using index; Using where EXPLAIN SELECT * FROM t1 , t2 WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,c PRIMARY 4 func 1 Using where +2 DEPENDENT SUBQUERY t3 index_subquery PRIMARY,c c 8 func,func 1 Using index; Using where SELECT * FROM t1 , t2 WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t); b a @@ -1917,7 +1976,7 @@ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where -1 PRIMARY ALL NULL NULL NULL NULL 3 Using where; Start temporary; End temporary +1 PRIMARY ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t3) 3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where SELECT * FROM t3 WHERE t3.b IN (SELECT v1.b FROM v1, t2 @@ -1931,8 +1990,8 @@ WHERE t3.b IN (SELECT v1.b FROM v1, t2 WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 -1 PRIMARY ref key1 key1 8 const,const 0 Start temporary -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY ref key1 key1 8 const,const 0 FirstMatch(t3) 3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where SELECT * FROM t3 WHERE t3.b IN (SELECT v1.b FROM v1, t2 @@ -1955,7 +2014,7 @@ EXPLAIN SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -1 PRIMARY ref key0 key0 10 test.t1.b,test.t1.a 2 FirstMatch(t1) +1 PRIMARY ref key0 key0 10 test.t1.b,test.t1.a 1 FirstMatch(t1) 3 DERIVED t2 ALL NULL NULL NULL NULL 2 SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a); a b @@ -2009,7 +2068,7 @@ EXPLAIN SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 3 Using where; Using filesort -1 PRIMARY ref key0 key0 4 v1.b 2 +1 PRIMARY ref key0 key0 4 v1.b 1 3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort 2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort DROP VIEW v1,v2; @@ -2370,7 +2429,7 @@ GROUP BY TABLE_SCHEMA) AS UNIQUES ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY COLUMNS ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +1 PRIMARY ref key0 key0 194 information_schema.COLUMNS.TABLE_SCHEMA 10 2 DERIVED STATISTICS ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.COLUMNS @@ -2439,10 +2498,14 @@ CREATE TABLE t2 (a int, INDEX(a)); INSERT INTO t2 VALUES (1), (2); INSERT INTO t1 SELECT a FROM (SELECT a FROM test.t1) AS s1 NATURAL JOIN t2 AS s2; +INSERT INTO t1 SELECT a FROM (SELECT a FROM test.t1) AS s1 NATURAL JOIN +t2 AS s2; SELECT * FROM t1; a 1 1 +1 +1 DELETE FROM t1; INSERT INTO t1 VALUES (1); PREPARE stmt FROM " @@ -2596,7 +2659,7 @@ EXPLAIN EXTENDED SELECT v1.c1, v1.c2 FROM v1, t2 WHERE v1.c1=t2.c1 AND v1.c2=t2.c2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t2.c2 2 100.00 Using where +1 PRIMARY ref key0 key0 5 test.t2.c2 1 100.00 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00 Warnings: Note 1003 /* select#1 */ select `v1`.`c1` AS `c1`,`v1`.`c2` AS `c2` from `test`.`v1` join `test`.`t2` where `v1`.`c1` = `test`.`t2`.`c1` and `v1`.`c2` = `test`.`t2`.`c2` @@ -2609,7 +2672,7 @@ SELECT t2.c1, t2.c2 FROM (SELECT c1 g, MAX(c2) m FROM t1 GROUP BY c1) t, t2 WHERE t.g=t2.c1 AND t.m=t2.c2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t2.c2 2 100.00 Using where +1 PRIMARY ref key0 key0 5 test.t2.c2 1 100.00 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00 Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from (/* select#2 */ select `test`.`t1`.`c1` AS `g`,max(`test`.`t1`.`c2`) AS `m` from `test`.`t1` group by `test`.`t1`.`c1`) `t` join `test`.`t2` where `t`.`g` = `test`.`t2`.`c1` and `t`.`m` = `test`.`t2`.`c2` @@ -2940,7 +3003,7 @@ GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 -1 PRIMARY ref key0 key0 7 test.m2.matintnum 2 +1 PRIMARY ref key0 key0 7 test.m2.matintnum 1 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 prepare stmt1 from @@ -3074,8 +3137,8 @@ EXPLAIN EXTENDED SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY ref key0 key0 5 test.t1.id 2 100.00 -2 DERIVED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index; Using filesort +1 PRIMARY ref key0 key0 5 test.t1.id 1 100.00 +2 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t1.id 1 100.00 Using where; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v2`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v2` on(`v2`.`order_pk` = `test`.`t1`.`id`) where 1 SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk; @@ -3088,8 +3151,8 @@ EXPLAIN EXTENDED SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY ref key0 key0 5 test.t1.id 2 100.00 -2 DERIVED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index; Using filesort +1 PRIMARY ref key0 key0 5 test.t1.id 1 100.00 +2 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 4 test.t1.id 1 100.00 Using where; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v3`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v3` on(`v3`.`order_pk` = `test`.`t1`.`id`) where 1 DROP VIEW v1,v2,v3; diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test index caccc7dafa1..13444676659 100644 --- a/mysql-test/main/derived_view.test +++ b/mysql-test/main/derived_view.test @@ -118,6 +118,7 @@ select * from t1 join v2 on f1=f2; show status like 'Handler_read%'; explain extended select * from v1 join v4 on f1=f2; +--source include/explain-no-costs.inc explain format=json select * from v1 join v4 on f1=f2; select * from v1 join v4 on f1=f2; @@ -142,6 +143,7 @@ select * from (select * from --echo materialized derived in materialized derived explain extended select * from (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz; +--source include/explain-no-costs.inc explain format=json select * from (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz; select * from (select * from @@ -153,6 +155,7 @@ explain extended select * from join (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z on x.f1 = z.f1; +--source include/explain-no-costs.inc explain format=json select * from (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x join @@ -194,6 +197,7 @@ join (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z on x.f1 = z.f1; +--source include/explain-no-costs.inc explain format=json select * from (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x @@ -218,6 +222,7 @@ select * from (select * from v4 group by 1) tt; --echo materialized view in merged derived explain extended select * from ( select * from v1 where f1 < 7) tt; +--source include/explain-no-costs.inc explain format=json select * from ( select * from v1 where f1 < 7) tt; select * from ( select * from v1 where f1 < 7) tt; @@ -234,6 +239,7 @@ select * from (select * from v7 group by 1) tt; --echo join of above two explain extended select * from v6 join v7 on f2=f1; +--source include/explain-no-costs.inc explain format=json select * from v6 join v7 on f2=f1; select * from v6 join v7 on f2=f1; @@ -1417,6 +1423,8 @@ INSERT INTO t1 VALUES (1); CREATE TABLE t2 (a int, INDEX(a)); INSERT INTO t2 VALUES (1), (2); +INSERT INTO t1 SELECT a FROM (SELECT a FROM test.t1) AS s1 NATURAL JOIN +t2 AS s2; INSERT INTO t1 SELECT a FROM (SELECT a FROM test.t1) AS s1 NATURAL JOIN t2 AS s2; SELECT * FROM t1; diff --git a/mysql-test/main/desc_index_range.result b/mysql-test/main/desc_index_range.result index 6b1f2e31c31..1dc17702a9f 100644 --- a/mysql-test/main/desc_index_range.result +++ b/mysql-test/main/desc_index_range.result @@ -194,7 +194,7 @@ test.t1 analyze status OK # Must use ROR-intersect: explain select * from t1 where b = 255 AND a IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge a,b b,a 5,5 NULL 1 Using intersect(b,a); Using where; Using index +1 SIMPLE t1 ref a,b b 5 const 2 Using where select * from t1 where b = 255 AND a IS NULL; pk a b 10000 NULL 255 diff --git a/mysql-test/main/distinct.result b/mysql-test/main/distinct.result index 888d3143f2c..02a76cf3e09 100644 --- a/mysql-test/main/distinct.result +++ b/mysql-test/main/distinct.result @@ -173,9 +173,9 @@ INSERT INTO t2 values (1),(2),(3); INSERT INTO t3 VALUES (1,'1'),(2,'2'),(1,'1'),(2,'2'); explain SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index a a 4 NULL 5 Using index; Using temporary -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using where -1 SIMPLE t3 ref a a 5 test.t1.b 2 Using index +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using where; Using temporary +1 SIMPLE t3 ref a a 5 test.t1.b 1 Using index +1 SIMPLE t2 ref a a 4 test.t1.a 1 Using index; Distinct SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a; a 1 @@ -522,8 +522,8 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2 WHERE t1_1.a = t1_2.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1_1 ALL PRIMARY NULL NULL NULL 3 Using temporary -1 SIMPLE t1_2 eq_ref PRIMARY PRIMARY 4 test.t1_1.a 1 Using index; Distinct +1 SIMPLE t1_2 index PRIMARY PRIMARY 4 NULL 3 Using index; Using temporary +1 SIMPLE t1_1 eq_ref PRIMARY PRIMARY 4 test.t1_2.a 1 EXPLAIN SELECT a FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL 3 Using index @@ -538,10 +538,10 @@ PRIMARY KEY (a,b)); INSERT INTO t2 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4); EXPLAIN SELECT DISTINCT a FROM t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL PRIMARY 4 NULL 4 Using index for group-by +1 SIMPLE t2 range NULL PRIMARY 4 NULL 3 Using index for group-by EXPLAIN SELECT DISTINCT a,a FROM t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL PRIMARY 4 NULL 4 Using index for group-by +1 SIMPLE t2 range NULL PRIMARY 4 NULL 3 Using index for group-by EXPLAIN SELECT DISTINCT b,a FROM t2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL PRIMARY 8 NULL 3 Using index @@ -754,9 +754,6 @@ INSERT INTO t1(a, b, c) VALUES (1, 1, 1), (1, 2, 1), (1, 2, 2), (1, 2, 3); -EXPLAIN SELECT DISTINCT a, b, d, c FROM t1; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL PRIMARY 16 NULL 7 Using index for group-by; Using temporary SELECT DISTINCT a, b, d, c FROM t1; a b d c 1 1 0 1 @@ -765,6 +762,13 @@ a b d c 1 2 0 1 1 2 0 2 1 2 0 3 +EXPLAIN SELECT DISTINCT a, b, d, c FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 16 NULL 6 Using index +INSERT INTO t1 SELECT seq/10,seq/10,seq/10,seq/10,seq from seq_1_to_100; +EXPLAIN SELECT DISTINCT a, b, d, c FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL PRIMARY 16 NULL 10 Using index for group-by; Using temporary DROP TABLE t1; # # Bug #46159: simple query that never returns diff --git a/mysql-test/main/distinct.test b/mysql-test/main/distinct.test index 32e189da98a..2f10d866560 100644 --- a/mysql-test/main/distinct.test +++ b/mysql-test/main/distinct.test @@ -4,6 +4,7 @@ # --source include/default_optimizer_switch.inc +--source include/have_sequence.inc --disable_warnings drop table if exists t1,t2,t3; --enable_warnings @@ -574,9 +575,10 @@ INSERT INTO t1(a, b, c) VALUES (1, 1, 1), (1, 2, 2), (1, 2, 3); -EXPLAIN SELECT DISTINCT a, b, d, c FROM t1; - SELECT DISTINCT a, b, d, c FROM t1; +EXPLAIN SELECT DISTINCT a, b, d, c FROM t1; +INSERT INTO t1 SELECT seq/10,seq/10,seq/10,seq/10,seq from seq_1_to_100; +EXPLAIN SELECT DISTINCT a, b, d, c FROM t1; DROP TABLE t1; diff --git a/mysql-test/main/except.result b/mysql-test/main/except.result index d83623370d5..ec7d085c70f 100644 --- a/mysql-test/main/except.result +++ b/mysql-test/main/except.result @@ -37,12 +37,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "REPLACED", "filtered": 100 } } @@ -53,12 +56,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "EXCEPT", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "REPLACED", "filtered": 100 } } @@ -85,6 +91,7 @@ ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -92,9 +99,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -108,6 +117,7 @@ ANALYZE "query_block": { "select_id": 2, "operation": "EXCEPT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -115,9 +125,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -139,6 +151,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -146,9 +159,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -164,6 +179,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -171,9 +187,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -187,6 +205,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -194,9 +213,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -281,12 +302,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "REPLACED", "filtered": 100 } }, @@ -295,7 +319,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 2, "rows": 2, + "cost": "REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -310,12 +336,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "EXCEPT", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "REPLACED", "filtered": 100 } }, @@ -324,7 +353,9 @@ EXPLAIN "table": { "table_name": "t4", "access_type": "ALL", + "loops": 2, "rows": 2, + "cost": "REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -355,6 +386,7 @@ ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -362,9 +394,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -376,9 +410,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 2, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -387,7 +423,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "119", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -397,6 +434,7 @@ ANALYZE "query_block": { "select_id": 2, "operation": "EXCEPT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -404,9 +442,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -418,9 +458,11 @@ ANALYZE "table": { "table_name": "t4", "access_type": "ALL", + "loops": 2, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -429,7 +471,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "119", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -448,6 +491,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -455,9 +499,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -473,6 +519,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -480,9 +527,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -494,9 +543,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 2, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -505,7 +556,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "119", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -515,6 +567,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -522,9 +575,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -536,9 +591,11 @@ ANALYZE "table": { "table_name": "t4", "access_type": "ALL", + "loops": 2, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -547,7 +604,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "119", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] diff --git a/mysql-test/main/except.test b/mysql-test/main/except.test index 090826ce94d..d253b288d3b 100644 --- a/mysql-test/main/except.test +++ b/mysql-test/main/except.test @@ -11,6 +11,7 @@ insert into t2 values (2,2),(3,3); EXPLAIN (select a,b from t1) except (select c,d from t2); EXPLAIN extended (select a,b from t1) except (select c,d from t2); EXPLAIN extended select * from ((select a,b from t1) except (select c,d from t2)) a; +--source include/analyze-format.inc EXPLAIN format=json (select a,b from t1) except (select c,d from t2); --source include/analyze-format.inc @@ -43,6 +44,7 @@ insert into t4 values (4,4),(7,7); EXPLAIN (select a,b,e,f from t1,t3) except (select c,d,g,h from t2,t4); EXPLAIN (select a,b,e,f from t1,t3) except (select c,d,g,h from t2,t4); EXPLAIN extended select * from ((select a,b,e,f from t1,t3) except (select c,d,g,h from t2,t4)) a; +--source include/analyze-format.inc EXPLAIN format=json (select a,b,e,f from t1,t3) except (select c,d,g,h from t2,t4); --source include/analyze-format.inc diff --git a/mysql-test/main/except_all.result b/mysql-test/main/except_all.result index df19abda077..f79f35ee932 100644 --- a/mysql-test/main/except_all.result +++ b/mysql-test/main/except_all.result @@ -65,12 +65,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -81,12 +84,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "EXCEPT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -120,6 +126,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -127,9 +134,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 7, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -145,6 +154,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -152,9 +162,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 7, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -168,6 +180,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -175,9 +188,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 7, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -204,6 +219,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -211,9 +227,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 7, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -229,6 +247,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -236,9 +255,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 7, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -252,6 +273,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -259,9 +281,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 7, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -387,12 +411,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -403,12 +430,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -417,7 +447,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 3, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -432,12 +464,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -446,7 +481,9 @@ EXPLAIN "table": { "table_name": "t4", "access_type": "ALL", + "loops": 2, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -482,6 +519,7 @@ ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -489,9 +527,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -503,9 +543,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 3, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -514,7 +556,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "119", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -524,6 +567,7 @@ ANALYZE "query_block": { "select_id": 2, "operation": "EXCEPT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -531,9 +575,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -545,9 +591,11 @@ ANALYZE "table": { "table_name": "t4", "access_type": "ALL", + "loops": 2, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -556,7 +604,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "119", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -574,6 +623,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -581,9 +631,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 9, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -599,6 +651,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -606,9 +659,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -620,9 +675,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 3, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -631,7 +688,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "119", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -641,6 +699,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "EXCEPT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -648,9 +707,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -662,9 +723,11 @@ ANALYZE "table": { "table_name": "t4", "access_type": "ALL", + "loops": 2, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -673,7 +736,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "119", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] diff --git a/mysql-test/main/except_all.test b/mysql-test/main/except_all.test index f873b220126..9f788f52dea 100644 --- a/mysql-test/main/except_all.test +++ b/mysql-test/main/except_all.test @@ -16,6 +16,7 @@ select * from t1 except all select * from t1 union all select * from t1 union al select * from (select * from t1 except all select * from t2) q1 except all select * from (select * from t1 except all select * from t2) q2; EXPLAIN select * from t1 except all select * from t2; +--source include/explain-no-costs.inc EXPLAIN format=json select * from t1 except all select * from t2; EXPLAIN extended (select * from t1) except all (select * from t2); EXPLAIN extended select * from ((select * from t1) except all (select * from t2)) a; @@ -53,6 +54,7 @@ select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4 EXPLAIN (select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4); EXPLAIN select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t; EXPLAIN extended select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t; +--source include/explain-no-costs.inc EXPLAIN format=json select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t; --source include/analyze-format.inc @@ -96,4 +98,4 @@ INSERT INTO t VALUES (1),(2); SELECT * FROM t WHERE i != ANY ( SELECT 3 EXCEPT ALL SELECT 3 ); -drop table t; \ No newline at end of file +drop table t; diff --git a/mysql-test/main/explain.result b/mysql-test/main/explain.result index 8db5e9f51ac..1e546d42d0a 100644 --- a/mysql-test/main/explain.result +++ b/mysql-test/main/explain.result @@ -325,7 +325,7 @@ DROP TABLE t1; # Bug#56814 Explain + subselect + fulltext crashes server # CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, -FULLTEXT KEY(f1),UNIQUE(f1)); +FULLTEXT KEY `fulltext` (f1), UNIQUE `unique` (f1)); INSERT INTO t1 VALUES ('test'); EXPLAIN SELECT 1 FROM t1 WHERE 1 > ALL((SELECT t1.f1 FROM t1 JOIN t1 a ON (MATCH(t1.f1) AGAINST ("")) @@ -333,7 +333,7 @@ WHERE t1.f1 GROUP BY t1.f1)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 2 SUBQUERY a system NULL NULL NULL NULL 1 -2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where +2 SUBQUERY t1 fulltext unique,fulltext fulltext 0 1 Using where PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE 1 > ALL((SELECT t1.f1 FROM t1 RIGHT OUTER JOIN t1 a @@ -343,12 +343,12 @@ EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 2 SUBQUERY a system NULL NULL NULL NULL 1 -2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where +2 SUBQUERY t1 fulltext unique,fulltext fulltext 0 1 Using where EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 2 SUBQUERY a system NULL NULL NULL NULL 1 -2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where +2 SUBQUERY t1 fulltext unique,fulltext fulltext 0 1 Using where DEALLOCATE PREPARE stmt; PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 @@ -359,12 +359,13 @@ EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 2 SUBQUERY a system NULL NULL NULL NULL 1 -2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where +2 SUBQUERY t1 fulltext unique,fulltext fulltext 0 1 Using where +INSERT into t1 values('test1'),('test2'),('test3'),('test4'),('test5'); EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 system NULL NULL NULL NULL 1 -2 SUBQUERY a system NULL NULL NULL NULL 1 -2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where +1 PRIMARY t1 index NULL unique 8 NULL 6 Using index +2 SUBQUERY t1 fulltext unique,fulltext fulltext 0 1 Using where +2 SUBQUERY a index NULL unique 8 NULL 6 Using index DEALLOCATE PREPARE stmt; DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/main/explain.test b/mysql-test/main/explain.test index 36595ba727c..0e4a3b8c2c0 100644 --- a/mysql-test/main/explain.test +++ b/mysql-test/main/explain.test @@ -254,7 +254,7 @@ DROP TABLE t1; --echo # CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, -FULLTEXT KEY(f1),UNIQUE(f1)); +FULLTEXT KEY `fulltext` (f1), UNIQUE `unique` (f1)); INSERT INTO t1 VALUES ('test'); EXPLAIN SELECT 1 FROM t1 @@ -279,6 +279,7 @@ PREPARE stmt FROM WHERE t1.f1 GROUP BY t1.f1))'; EXECUTE stmt; +INSERT into t1 values('test1'),('test2'),('test3'),('test4'),('test5'); EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/mysql-test/main/explain_innodb.result b/mysql-test/main/explain_innodb.result index b46665c279c..0bdd5a44985 100644 --- a/mysql-test/main/explain_innodb.result +++ b/mysql-test/main/explain_innodb.result @@ -15,6 +15,6 @@ explain SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 DERIVED t1 range NULL id 53 NULL 2 Using index for group-by +2 DERIVED t1 range NULL id 53 NULL 1 Using index for group-by SET GLOBAL slow_query_log = @sql_tmp; drop table t1; diff --git a/mysql-test/main/explain_json.result b/mysql-test/main/explain_json.result index 3c3c0688ab8..806773d154c 100644 --- a/mysql-test/main/explain_json.result +++ b/mysql-test/main/explain_json.result @@ -6,12 +6,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -33,12 +36,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t0.a < 3" } @@ -59,12 +65,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t0.a is not null" } @@ -78,7 +87,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t0.a"], + "loops": 10, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -93,6 +104,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -102,7 +114,9 @@ EXPLAIN "key": "a1", "key_length": "5", "used_key_parts": ["a1"], + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t2.a1 < 5" } @@ -115,6 +129,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -138,7 +153,9 @@ EXPLAIN } ] }, + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a1 = 1 or t2.b1 = 2" } @@ -151,6 +168,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -174,7 +192,9 @@ EXPLAIN } ] }, + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a1 = 1 or t2.b1 = 2 and t2.b2 = 3" } @@ -188,6 +208,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -211,7 +232,9 @@ EXPLAIN } ] }, + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a1 = 1 and t2.a2 = 1 or t2.b1 = 2 and t2.b2 = 1" } @@ -225,12 +248,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t0.a is not null" } @@ -244,7 +270,9 @@ EXPLAIN "key_length": "10", "used_key_parts": ["b1", "b2"], "ref": ["test.t0.a", "const"], + "loops": 10, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -266,12 +294,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "A", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -282,12 +313,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "B", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -307,12 +341,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "A", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -323,12 +360,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "B", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -349,12 +389,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -365,12 +408,15 @@ EXPLAIN "state": "uninitialized", "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t0.a" } @@ -389,12 +435,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t0.a > (subquery#2) or t0.a < 3" } @@ -406,12 +455,15 @@ EXPLAIN "state": "uninitialized", "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t0.a" } @@ -435,12 +487,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "tbl1", "access_type": "ALL", + "loops": 1, "rows": 100, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tbl1.b < 3" } @@ -450,7 +505,9 @@ EXPLAIN "table": { "table_name": "tbl2", "access_type": "ALL", + "loops": 100, "rows": 100, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tbl2.b < 5" }, @@ -538,12 +595,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -566,17 +626,21 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tbl.cnt > 0", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "cnt > 0", "filesort": { "sort_key": "t1.a", @@ -586,7 +650,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -607,12 +673,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "tbl2", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tbl2.a is not null" } @@ -626,12 +695,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["cnt"], "ref": ["test.tbl2.a"], - "rows": 2, + "loops": 10, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "tbl1.cnt = tbl2.a", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -640,7 +712,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -663,12 +737,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a is not null" } @@ -682,19 +759,24 @@ EXPLAIN "key_length": "4", "used_key_parts": ["max(a)"], "ref": ["test.t1.a"], + "loops": 10, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -713,18 +795,20 @@ EXPLAIN create table t2 like t1; insert into t2 select * from t1; explain format=json -select * from t1,t2 where t1.a in ( select a from t0); +select * from t1,t2 where t1.a in ( select seq+0 from seq_1_to_100); EXPLAIN { "query_block": { "select_id": 1, - "const_condition": "1", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -734,11 +818,12 @@ EXPLAIN "access_type": "eq_ref", "possible_keys": ["distinct_key"], "key": "distinct_key", - "key_length": "4", - "used_key_parts": ["a"], + "key_length": "8", + "used_key_parts": ["seq+0"], "ref": ["func"], "rows": 1, "filtered": 100, + "attached_condition": "t1.a = seq_1_to_100.seq + 0", "materialized": { "unique": 1, "query_block": { @@ -746,10 +831,16 @@ EXPLAIN "nested_loop": [ { "table": { - "table_name": "t0", - "access_type": "ALL", - "rows": 10, - "filtered": 100 + "table_name": "seq_1_to_100", + "access_type": "index", + "key": "PRIMARY", + "key_length": "8", + "used_key_parts": ["seq"], + "loops": 1, + "rows": 100, + "cost": "COST_REPLACED", + "filtered": 100, + "using_index": true } } ] @@ -762,11 +853,13 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 10, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", - "buffer_size": "1Kb", + "buffer_size": "19Kb", "join_type": "BNL" } } @@ -787,12 +880,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -801,7 +897,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 10, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "first_match": "t2" }, @@ -830,12 +928,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -846,8 +947,10 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 10, "rows": 10, - "filtered": 100 + "cost": "COST_REPLACED", + "filtered": 10 }, "buffer_type": "flat", "buffer_size": "206", @@ -874,6 +977,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -883,7 +987,9 @@ EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a < 3", "mrr_type": "Rowid-ordered scan" @@ -900,12 +1006,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "tbl1", "access_type": "ALL", + "loops": 1, "rows": 100, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -916,7 +1025,9 @@ EXPLAIN "table_name": "tbl2", "access_type": "ALL", "possible_keys": ["a"], + "loops": 100, "rows": 100, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -930,14 +1041,15 @@ drop table t0; # MDEV-7265: "Full scan on NULL key", the join case # CREATE TABLE t1 (a INT, KEY(a)); -INSERT INTO t1 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(5),(6),(7); CREATE TABLE t2 (b INT); -INSERT INTO t2 VALUES (3),(4); +INSERT INTO t2 VALUES (3),(4),(9),(10),(11); EXPLAIN FORMAT=JSON SELECT * FROM t1 AS outer_t1 WHERE a <> ALL ( SELECT a FROM t1, t2 WHERE b <> outer_t1.a ); EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -946,7 +1058,9 @@ EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], - "rows": 2, + "loops": 1, + "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "!(outer_t1.a,(subquery#2))", "using_index": true @@ -957,6 +1071,7 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "trigcond(t1.a is null)", "nested_loop": [ { @@ -969,7 +1084,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["func"], - "rows": 2, + "loops": 1, + "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "trigcond((outer_t1.a) = t1.a or t1.a is null)", "using_index": true @@ -981,7 +1098,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", - "rows": 2, + "loops": 3, + "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -1013,13 +1132,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "((20000,(subquery#2) >= 20000))", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1028,12 +1150,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "tbl1", "access_type": "ALL", + "loops": 1, "rows": 100, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1042,7 +1167,9 @@ EXPLAIN "table": { "table_name": "tbl2", "access_type": "ALL", + "loops": 100, "rows": 100, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -1071,14 +1198,17 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "!(t1.a,t1.a in (subquery#2))" + "attached_condition": "!(t1.a,(subquery#2))" } } ], @@ -1086,13 +1216,18 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", + "having_condition": "trigcond(t2.b is null)", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, - "filtered": 100 + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "trigcond((t1.a) = t2.b or t2.b is null)" } } ] @@ -1129,6 +1264,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1137,7 +1273,9 @@ EXPLAIN "key": "a", "key_length": "10", "used_key_parts": ["a", "b"], + "loops": 1, "rows": 101, + "cost": "COST_REPLACED", "filtered": 100, "using_index_for_group_by": true } @@ -1153,6 +1291,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1163,9 +1302,11 @@ ANALYZE "key": "a", "key_length": "10", "used_key_parts": ["a", "b"], + "loops": 1, "r_loops": 1, "rows": 101, "r_rows": 100, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1223,26 +1364,35 @@ analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status Table is already up to date +select count(*) from t1; +count(*) +128 explain select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by +1 SIMPLE t1 range NULL idx_t1_2 147 NULL 17 Using where; Using index for group-by explain select count(distinct a1,a2,b,c) from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL idx_t1_1 163 NULL 65 Using where; Using index for group-by +1 SIMPLE t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index +explain select count(distinct a1,a2,b) from t1 where a1 >= "" and (a2 >= 'b') and (b = 'a'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 1 Using where; Using index for group-by explain format=json select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a'); EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "range", - "key": "idx_t1_1", + "key": "idx_t1_2", "key_length": "147", "used_key_parts": ["a1", "a2", "b"], + "loops": 1, "rows": 17, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 'a' and t1.a2 >= 'b'", "using_index_for_group_by": true @@ -1256,17 +1406,46 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "index", + "key": "idx_t1_1", + "key_length": "163", + "used_key_parts": ["a1", "a2", "b", "c"], + "loops": 1, + "rows": 128, + "cost": "COST_REPLACED", + "filtered": 0.198364258, + "attached_condition": "t1.b = 'a' and t1.c = 'i121' and t1.a2 >= 'b'", + "using_index": true + } + } + ] + } +} +explain format=json select count(distinct a1,a2,b) from t1 where a1 >= "" and (a2 >= 'b') and (b = 'a'); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "range", + "possible_keys": ["idx_t1_0", "idx_t1_1", "idx_t1_2"], "key": "idx_t1_1", - "key_length": "163", - "used_key_parts": ["a1", "a2", "b", "c"], - "rows": 65, + "key_length": "147", + "used_key_parts": ["a1", "a2", "b"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "t1.b = 'a' and t1.c = 'i121' and t1.a2 >= 'b'", + "attached_condition": "t1.b = 'a' and t1.a1 >= '' and t1.a2 >= 'b'", "using_index_for_group_by": true } } @@ -1284,12 +1463,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = _latin1'\xDF'" } @@ -1308,12 +1490,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(case when convert(t1.a using utf8mb3) = (_utf8mb3'a' collate utf8mb3_bin) then NULL else t1.a end)" } @@ -1341,6 +1526,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "TOP > t2.a", "filesort": { "sort_key": "t2.a", @@ -1350,7 +1536,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 256, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1365,6 +1553,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t2.a", "temporary_table": { @@ -1373,7 +1562,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 256, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1399,6 +1590,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t2.a", "temporary_table": { @@ -1407,7 +1599,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 256, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1468,7 +1662,7 @@ insert into t2 values (1),(2); explain select * from t1 left join t2 on t2.pk > 10 and t2.pk < 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 const PRIMARY NULL NULL NULL 1 Impossible ON condition +1 SIMPLE t2 const PRIMARY NULL NULL NULL 0 Impossible ON condition 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 explain format=json select * from t1 left join t2 on t2.pk > 10 and t2.pk < 0; @@ -1476,6 +1670,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { @@ -1483,8 +1678,8 @@ EXPLAIN "table_name": "t2", "access_type": "const", "possible_keys": ["PRIMARY"], - "rows": 1, - "filtered": 100, + "rows": 0, + "filtered": 0, "impossible_on_condition": true } }, @@ -1492,7 +1687,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1508,6 +1705,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "const_condition": "1", @@ -1518,9 +1716,9 @@ ANALYZE "access_type": "const", "possible_keys": ["PRIMARY"], "r_loops": 0, - "rows": 1, + "rows": 0, "r_rows": null, - "filtered": 100, + "filtered": 0, "r_filtered": null, "impossible_on_condition": true } @@ -1529,9 +1727,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1553,12 +1753,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1571,7 +1774,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["pk"], "ref": ["test.t1.a"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "trigcond(t2.pk is null) and trigcond(trigcond(t1.a is not null))", "using_index": true, @@ -1590,6 +1795,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1597,9 +1803,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1615,9 +1823,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["pk"], "ref": ["test.t1.a"], + "loops": 2, "r_loops": 2, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1642,13 +1852,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a is not null" } @@ -1662,7 +1875,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["pk"], "ref": ["test.t1.a"], + "loops": 2, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "using_index": true, "distinct": true @@ -1681,6 +1896,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "temporary_table": { @@ -1689,9 +1905,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1708,9 +1926,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["pk"], "ref": ["test.t1.a"], + "loops": 2, "r_loops": 2, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1748,12 +1968,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.a is not null" } @@ -1768,7 +1991,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t3.a"], + "loops": 10, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "index_condition_bka": "t4.b + 1 <= t3.b + 1" }, @@ -1790,6 +2015,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1797,9 +2023,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1817,9 +2045,11 @@ ANALYZE "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t3.a"], + "loops": 10, "r_loops": 1, "rows": 1, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1830,7 +2060,8 @@ ANALYZE "buffer_size": "400", "join_type": "BKA", "mrr_type": "Rowid-ordered scan", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -1852,12 +2083,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1868,13 +2102,16 @@ EXPLAIN "state": "uninitialized", "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "outer_ref_condition": "t0.a < 5", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b < t0.a" } @@ -1897,6 +2134,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -1905,7 +2143,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1919,6 +2159,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -1927,7 +2168,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1941,6 +2184,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -1949,7 +2193,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1971,12 +2217,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -1987,7 +2236,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 2, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -2001,8 +2252,10 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 4, "rows": 2, - "filtered": 100 + "cost": "COST_REPLACED", + "filtered": 25 }, "buffer_type": "incremental", "buffer_size": "109", diff --git a/mysql-test/main/explain_json.test b/mysql-test/main/explain_json.test index 17e2da4754c..6403fdefdd7 100644 --- a/mysql-test/main/explain_json.test +++ b/mysql-test/main/explain_json.test @@ -2,6 +2,7 @@ # EXPLAIN FORMAT=JSON tests. These are tests developed for MariaDB. # --source include/default_optimizer_switch.inc +--source include/have_sequence.inc --disable_warnings drop table if exists t0,t1,t2; @@ -10,10 +11,13 @@ drop table if exists t0,t1,t2; create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +--source include/explain-no-costs.inc explain format=json select * from t0; +--source include/explain-no-costs.inc explain format=json select * from t0 where 1>2; +--source include/explain-no-costs.inc explain format=json select * from t0 where a<3; --echo # Try a basic join @@ -25,22 +29,28 @@ select 'filler' from t0 a, t0 b, t0 c; +--source include/explain-no-costs.inc explain format=json select * from t0,t1 where t1.a=t0.a; --echo # Try range and index_merge create table t2 (a1 int, a2 int, b1 int, b2 int, key(a1,a2), key(b1,b2)); insert into t2 select a,a,a,a from t1; +--source include/explain-no-costs.inc explain format=json select * from t2 where a1<5; +--source include/explain-no-costs.inc explain format=json select * from t2 where a1=1 or b1=2; +--source include/explain-no-costs.inc explain format=json select * from t2 where a1=1 or (b1=2 and b2=3); +--source include/explain-no-costs.inc explain format=json select * from t2 where (a1=1 and a2=1) or (b1=2 and b2=1); --echo # Try ref access on two key components +--source include/explain-no-costs.inc explain format=json select * from t0,t2 where t2.b1=t0.a and t2.b2=4; drop table t1,t2; @@ -48,7 +58,9 @@ drop table t1,t2; --echo # --echo # Try a UNION --echo # +--source include/explain-no-costs.inc explain format=json select * from t0 A union select * from t0 B; +--source include/explain-no-costs.inc explain format=json select * from t0 A union all select * from t0 B; --echo # @@ -56,8 +68,10 @@ explain format=json select * from t0 A union all select * from t0 B; --echo # create table t1 (a int, b int); insert into t1 select a,a from t0; +--source include/explain-no-costs.inc explain format=json select a, a > (select max(b) from t1 where t1.b=t0.a) from t0; +--source include/explain-no-costs.inc explain format=json select * from t0 where a > (select max(b) from t1 where t1.b=t0.a) or a < 3 ; @@ -70,6 +84,7 @@ drop table t1; create table t1 (a int, b int); insert into t1 select tbl1.a+10*tbl2.a, tbl1.a+10*tbl2.a from t0 tbl1, t0 tbl2; +--source include/explain-no-costs.inc explain format=json select * from t1 tbl1, t1 tbl2 where tbl1.a=tbl2.a and tbl1.b < 3 and tbl2.b < 5; @@ -78,16 +93,22 @@ drop table t1; --echo # --echo # Single-table UPDATE/DELETE, INSERT --echo # +--source include/explain-no-costs.inc explain format=json delete from t0; +--source include/explain-no-costs.inc explain format=json delete from t0 where 1 > 2; +--source include/explain-no-costs.inc explain format=json delete from t0 where a < 3; +--source include/explain-no-costs.inc explain format=json update t0 set a=3 where a in (2,3,4); +--source include/explain-no-costs.inc explain format=json insert into t0 values (1); create table t1 like t0; +--source include/explain-no-costs.inc explain format=json insert into t1 values ((select max(a) from t0)); drop table t1; @@ -97,10 +118,12 @@ drop table t1; --echo # create table t1 (a int, b int); insert into t1 select a,a from t0; +--source include/explain-no-costs.inc explain format=json select * from (select a, count(*) as cnt from t1 group by a) as tbl where cnt>0; +--source include/explain-no-costs.inc explain format=json select * from (select a, count(*) as cnt from t1 group by a) as tbl1, t1 as tbl2 where cnt=tbl2.a; @@ -108,6 +131,7 @@ tbl2 where cnt=tbl2.a; --echo # --echo # Non-merged semi-join (aka JTBM) --echo # +--source include/explain-no-costs.inc explain format=json select * from t1 where a in (select max(a) from t1 group by b); @@ -116,14 +140,16 @@ select * from t1 where a in (select max(a) from t1 group by b); --echo # create table t2 like t1; insert into t2 select * from t1; +--source include/explain-no-costs.inc explain format=json -select * from t1,t2 where t1.a in ( select a from t0); +select * from t1,t2 where t1.a in ( select seq+0 from seq_1_to_100); --echo # --echo # First-Match --echo # explain select * from t2 where t2.a in ( select a from t1 where t1.b=t2.b); +--source include/explain-no-costs.inc explain format=json select * from t2 where t2.a in ( select a from t1 where t1.b=t2.b); @@ -134,6 +160,7 @@ set @tmp= @@optimizer_switch; set optimizer_switch='firstmatch=off'; explain select * from t2 where t2.a in ( select a from t1 where t1.b=t2.b); +--source include/explain-no-costs.inc explain format=json select * from t2 where t2.a in ( select a from t1 where t1.b=t2.b); set optimizer_switch=@tmp; @@ -148,10 +175,12 @@ insert into t1 select tbl1.a+10*tbl2.a, 12345 from t0 tbl1, t0 tbl2; set @tmp= @@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on'; +--source include/explain-no-costs.inc explain format=json select * from t1 where a < 3; --echo # 'Range checked for each record' set optimizer_switch=@tmp; +--source include/explain-no-costs.inc explain format=json select * from t1 tbl1, t1 tbl2 where tbl2.a < tbl1.b; @@ -163,11 +192,12 @@ drop table t0; --echo # CREATE TABLE t1 (a INT, KEY(a)); -INSERT INTO t1 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(5),(6),(7); CREATE TABLE t2 (b INT); -INSERT INTO t2 VALUES (3),(4); +INSERT INTO t2 VALUES (3),(4),(9),(10),(11); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM t1 AS outer_t1 WHERE a <> ALL ( SELECT a FROM t1, t2 WHERE b <> outer_t1.a ); DROP TABLE t1,t2; @@ -181,6 +211,7 @@ 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 tbl1.a+10*tbl2.a, 1234 from t0 tbl1, t0 tbl2; +--source include/explain-no-costs.inc explain format=json select * from t0 where @@ -199,6 +230,7 @@ INSERT INTO t1 VALUES (1),(2); CREATE TABLE t2 (b INT); INSERT INTO t2 VALUES (3),(4); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE a <> ALL ( SELECT b FROM t2 ); DROP TABLE t1, t2; @@ -220,6 +252,7 @@ insert into t2 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 (a int, b int, c int, d int, key(a,b,c)); insert into t1 select A.a, B.a, C.a, D.a from t2 A, t2 B, t2 C, t2 D; explain select count(distinct b) from t1 group by a; +--source include/explain-no-costs.inc explain format=json select count(distinct b) from t1 group by a; --source include/analyze-format.inc analyze format=json select count(distinct b) from t1 group by a; @@ -271,13 +304,20 @@ create index idx_t1_0 on t1 (a1); create index idx_t1_1 on t1 (a1,a2,b,c); create index idx_t1_2 on t1 (a1,a2,b); analyze table t1; +select count(*) from t1; explain select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a'); explain select count(distinct a1,a2,b,c) from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121'); +explain select count(distinct a1,a2,b) from t1 where a1 >= "" and (a2 >= 'b') and (b = 'a'); +--source include/explain-no-costs.inc explain format=json select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a'); + +--source include/explain-no-costs.inc explain format=json select count(distinct a1,a2,b,c) from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121'); +--source include/explain-no-costs.inc +explain format=json select count(distinct a1,a2,b) from t1 where a1 >= "" and (a2 >= 'b') and (b = 'a'); drop table t1; --echo # @@ -285,6 +325,7 @@ drop table t1; --echo # CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); INSERT INTO t1 VALUES ('a'),('b'); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE a=_latin1 0xDF; DROP TABLE t1; @@ -293,6 +334,7 @@ DROP TABLE t1; --echo # CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); INSERT INTO t1 VALUES ('a'),('A'); +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE NULLIF(a,_utf8'a' COLLATE utf8_bin); DROP TABLE t1; @@ -310,12 +352,16 @@ create table t2 ( ); insert into t2 select A.a*1000 + B.a, A.a*1000 + B.a from t0 A, t1 B; --echo # normal HAVING +--source include/explain-no-costs.inc explain format=json select a, max(b) as TOP from t2 group by a having TOP > a; --echo # HAVING is always TRUE (not printed) +--source include/explain-no-costs.inc explain format=json select a, max(b) as TOP from t2 group by a having 1<>2; --echo # HAVING is always FALSE (intercepted by message) +--source include/explain-no-costs.inc explain format=json select a, max(b) as TOP from t2 group by a having 1=2; --echo # HAVING is absent +--source include/explain-no-costs.inc explain format=json select a, max(b) as TOP from t2 group by a; drop table t0, t1, t2; @@ -327,6 +373,7 @@ drop table t0, t1, t2; create table t1 (i int) engine=myisam; explain select * from t1; +--source include/explain-no-costs.inc explain format=json select * from t1; --source include/analyze-format.inc @@ -343,6 +390,7 @@ insert into t2 values (1),(2); explain select * from t1 left join t2 on t2.pk > 10 and t2.pk < 0; +--source include/explain-no-costs.inc explain format=json select * from t1 left join t2 on t2.pk > 10 and t2.pk < 0; --source include/analyze-format.inc @@ -352,6 +400,7 @@ select * from t1 left join t2 on t2.pk > 10 and t2.pk < 0; --echo # Check ET_NOT_EXISTS: explain select * from t1 left join t2 on t2.pk=t1.a where t2.pk is null; +--source include/explain-no-costs.inc explain format=json select * from t1 left join t2 on t2.pk=t1.a where t2.pk is null; --source include/analyze-format.inc @@ -361,6 +410,7 @@ select * from t1 left join t2 on t2.pk=t1.a where t2.pk is null; --echo # Check ET_DISTINCT explain select distinct t1.a from t1 join t2 on t2.pk=t1.a; +--source include/explain-no-costs.inc explain format=json select distinct t1.a from t1 join t2 on t2.pk=t1.a; --source include/analyze-format.inc @@ -387,6 +437,7 @@ set optimizer_switch='mrr=on'; set join_cache_level=6; explain select * from t3,t4 where t3.a=t4.a and (t4.b+1 <= t3.b+1); +--source include/explain-no-costs.inc explain format=json select * from t3,t4 where t3.a=t4.a and (t4.b+1 <= t3.b+1); --source include/analyze-format.inc @@ -405,6 +456,7 @@ 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; +--source include/explain-no-costs.inc explain format=json select a, (select max(a) from t1 where t0.a<5 and t1.b ALL NULL NULL NULL NULL 2 Using filesort -2 DERIVED t1 range t1_name t1_name 103 NULL 3 Using where; Using index +2 DERIVED t1 range t1_name t1_name 206 NULL 3 Using where; Using index for group-by with temp_table as ( select first_name, last_name from t1 @@ -1007,12 +1061,12 @@ id first_name last_name score 3 John Smith 6 select * from t1 order by first_name desc fetch first 3 rows with ties; id first_name last_name score -8 Silvia Ganush 10 -2 John Doe 6 -3 John Smith 6 -4 John Smith 6 -5 John Smith 7 -6 John Elton 8.1 +# Silvia # # +# John # # +# John # # +# John # # +# John # # +# John # # (select * from t1 order by 1 fetch first 3 rows with ties) intersect (select * from t1 order by first_name desc fetch first 3 rows with ties) diff --git a/mysql-test/main/fetch_first.test b/mysql-test/main/fetch_first.test index 62cdd717f81..3cec50257fe 100644 --- a/mysql-test/main/fetch_first.test +++ b/mysql-test/main/fetch_first.test @@ -349,8 +349,15 @@ order by first_name, last_name offset 1 rows fetch first 3 rows with ties; +--source include/analyze-format.inc +analyze FORMAT=JSON select * from t1 -order by first_name, last_name +order by first_name, last_name, score +offset 2 rows +fetch first 3 rows only; + +select * from t1 +order by first_name, last_name, score offset 2 rows fetch first 3 rows only; @@ -360,7 +367,7 @@ offset 2 rows fetch first 3 rows with ties; select * from t1 -order by first_name, last_name +order by first_name, last_name, score offset 3 rows fetch first 3 rows only; @@ -614,7 +621,12 @@ where first_name != 'John' order by first_name fetch first 2 rows with ties; - +explain select first_name, last_name +from t1 +where first_name != 'John' +group by first_name, last_name +order by first_name +fetch first 2 rows with ties; select first_name, last_name from t1 @@ -769,6 +781,7 @@ fetch first 1 row with ties; --echo # Test union-like operator with multiple fetch first clauses. --echo # select * from t1 order by 1 fetch first 3 rows with ties; +--replace_column 1 # 3 # 4 # select * from t1 order by first_name desc fetch first 3 rows with ties; --sorted_result diff --git a/mysql-test/main/filesort_debug.result b/mysql-test/main/filesort_debug.result index 4aa40592be7..0280d378778 100644 --- a/mysql-test/main/filesort_debug.result +++ b/mysql-test/main/filesort_debug.result @@ -63,6 +63,7 @@ c27 TEXT, c28 TEXT, primary key (pk) ); +insert into t1 (pk) values (1),(2),(3); CALL mtr.add_suppression("Out of sort memory"); DELETE IGNORE FROM t1 ORDER BY c26,c7,c23,c4,c25,c5,c20, c19,c21,c8,c1,c27,c28,c3,c9,c22,c24,c6,c2,pk LIMIT 2; diff --git a/mysql-test/main/filesort_debug.test b/mysql-test/main/filesort_debug.test index a8833617c09..d5dc6a89507 100644 --- a/mysql-test/main/filesort_debug.test +++ b/mysql-test/main/filesort_debug.test @@ -86,6 +86,8 @@ CREATE TABLE t1 ( primary key (pk) ); +insert into t1 (pk) values (1),(2),(3); + CALL mtr.add_suppression("Out of sort memory"); --error ER_OUT_OF_SORTMEMORY diff --git a/mysql-test/main/fulltext.result b/mysql-test/main/fulltext.result index 3acde6121ec..3a338fdc847 100644 --- a/mysql-test/main/fulltext.result +++ b/mysql-test/main/fulltext.result @@ -594,6 +594,9 @@ CREATE TABLE t2 (a int, b2 char(10), FULLTEXT KEY b2 (b2)); INSERT INTO t2 VALUES (1,'Scargill'); CREATE TABLE t3 (a int, b int); INSERT INTO t3 VALUES (1,1), (2,1); +SELECT * FROM t2 where MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE); +a b2 +1 Scargill # t2 should use full text index EXPLAIN SELECT count(*) FROM t1 WHERE @@ -603,8 +606,8 @@ WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE) ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED t2 fulltext b2 b2 0 1 Using where -2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 fulltext b2 b2 0 1 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where # should return 0 SELECT count(*) FROM t1 WHERE not exists( diff --git a/mysql-test/main/fulltext.test b/mysql-test/main/fulltext.test index 8b90c9cd81d..ef690be2314 100644 --- a/mysql-test/main/fulltext.test +++ b/mysql-test/main/fulltext.test @@ -547,6 +547,8 @@ INSERT INTO t2 VALUES (1,'Scargill'); CREATE TABLE t3 (a int, b int); INSERT INTO t3 VALUES (1,1), (2,1); +SELECT * FROM t2 where MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE); + --echo # t2 should use full text index EXPLAIN SELECT count(*) FROM t1 WHERE diff --git a/mysql-test/main/func_group.result b/mysql-test/main/func_group.result index 8f9c27eeb86..de64d01ed4c 100644 --- a/mysql-test/main/func_group.result +++ b/mysql-test/main/func_group.result @@ -1820,7 +1820,7 @@ CREATE TABLE t1(f1 YEAR(4)); INSERT INTO t1 VALUES (0000),(2001); (SELECT MAX(f1) FROM t1) UNION (SELECT MAX(f1) FROM t1); Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def MAX(f1) MAX(f1) 13 4 4 Y 32864 0 63 +def MAX(f1) MAX(f1) 13 4 4 Y 49248 0 63 MAX(f1) 2001 DROP TABLE t1; @@ -1856,9 +1856,8 @@ NULL EXPLAIN EXTENDED SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 20.00 Using where; FirstMatch 1 PRIMARY t1 range a a 4 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join) -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where Warnings: Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = 1 and `test`.`t2`.`b` = 2 and `test`.`t1`.`a` < 10 SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; diff --git a/mysql-test/main/func_group_innodb.result b/mysql-test/main/func_group_innodb.result index f5a823e4638..9f69f424f33 100644 --- a/mysql-test/main/func_group_innodb.result +++ b/mysql-test/main/func_group_innodb.result @@ -246,12 +246,12 @@ INSERT INTO t1(a, b, c) VALUES ('', 'a', 1), ('', 'a', 1), ('', 'a', 2), ('', 'a', 2), ('', 'a', 3), ('', 'a', 3), ('', 'a', 4), ('', 'a', 4), ('', 'a', 5), ('', 'a', 5); ANALYZE TABLE t1; -SELECT MIN(c) FROM t1 GROUP BY b; -MIN(c) -0 EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL b 263 NULL 2 Using index for group-by +SELECT MIN(c) FROM t1 GROUP BY b; +MIN(c) +0 DROP TABLE t1; # # MDEV-17589: Stack-buffer-overflow with indexed varchar (utf8) field diff --git a/mysql-test/main/func_group_innodb.test b/mysql-test/main/func_group_innodb.test index b1f9a28b190..ca6b083848c 100644 --- a/mysql-test/main/func_group_innodb.test +++ b/mysql-test/main/func_group_innodb.test @@ -199,8 +199,8 @@ INSERT INTO t1(a, b, c) VALUES ANALYZE TABLE t1; -- enable_result_log -SELECT MIN(c) FROM t1 GROUP BY b; EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b; +SELECT MIN(c) FROM t1 GROUP BY b; DROP TABLE t1; diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index 7188c5de205..c3c2a883270 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -3803,21 +3803,13 @@ SET @sav_slow_query_log= @@session.slow_query_log; SET @@session.slow_query_log= ON; SELECT current_timestamp(6),fn_sleep_before_now() INTO @ts_cur, @ts_func; SELECT a FROM t_ts LIMIT 1 into @ts_func; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT a FROM t_trig LIMIT 1 into @ts_trig; -Warnings: -Warning 1287 ' INTO FROM...' instead DELETE FROM t_ts; DELETE FROM t_trig; SET @@session.slow_query_log= OFF; SELECT current_timestamp(6),fn_sleep_before_now() INTO @ts_cur, @func_ts; SELECT a FROM t_ts LIMIT 1 into @ts_func; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT a FROM t_trig LIMIT 1 into @ts_trig; -Warnings: -Warning 1287 ' INTO FROM...' instead SET @@session.slow_query_log= @sav_slow_query_log; DROP FUNCTION fn_sleep_before_now; DROP TRIGGER trg_insert_t_ts; diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result index b067819acfd..9d95f2fa478 100644 --- a/mysql-test/main/grant.result +++ b/mysql-test/main/grant.result @@ -1472,8 +1472,6 @@ declare tmp varchar(30); select col1 from test limit 1 into tmp; return '1'; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create view v1 as select test.* from test where test.col1=test_function(); grant update (col1) on v1 to 'greg'@'localhost'; drop user 'greg'@'localhost'; diff --git a/mysql-test/main/grant2.result b/mysql-test/main/grant2.result index 414d61243e9..ebf83272713 100644 --- a/mysql-test/main/grant2.result +++ b/mysql-test/main/grant2.result @@ -452,8 +452,6 @@ INSERT INTO t2 VALUES (1); DROP FUNCTION IF EXISTS f2; CREATE FUNCTION f2 () RETURNS INT BEGIN DECLARE v INT; SELECT s1 FROM t2 INTO v; RETURN v; END// -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT f2(); f2() 1 diff --git a/mysql-test/main/greedy_optimizer.result b/mysql-test/main/greedy_optimizer.result index 55812cb6ff9..2bf67d5f6d8 100644 --- a/mysql-test/main/greedy_optimizer.result +++ b/mysql-test/main/greedy_optimizer.result @@ -127,7 +127,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 1.650935 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 @@ -139,55 +139,55 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 1.650935 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.602062 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.602062 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.621783 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.621783 set optimizer_prune_level=0; select @@optimizer_prune_level; @@optimizer_prune_level @@ -198,108 +198,108 @@ select @@optimizer_search_depth; 0 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 Using where +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1371.437037 +Last_query_cost 1.405838 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 Using where +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 Using where show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1371.437037 +Last_query_cost 1.405838 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 362.618727 +Last_query_cost 0.494824 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 362.618727 +Last_query_cost 0.494824 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 362.618727 +Last_query_cost 0.453844 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 362.618727 +Last_query_cost 0.453844 set optimizer_search_depth=1; select @@optimizer_search_depth; @@optimizer_search_depth 1 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t7 index PRIMARY PRIMARY 4 NULL 21 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 34.291074 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t7 index PRIMARY PRIMARY 4 NULL 21 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 34.291074 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index +1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 9 Using index +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) @@ -307,19 +307,19 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 14.789792 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where +1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 9 Using index +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 14.789792 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where @@ -331,7 +331,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 1.698747 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where @@ -343,83 +343,83 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 1.698747 set optimizer_search_depth=62; select @@optimizer_search_depth; @@optimizer_search_depth 62 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 Using where +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1371.437037 +Last_query_cost 1.405838 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 Using where +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 Using where show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1371.437037 +Last_query_cost 1.405838 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 362.618727 +Last_query_cost 0.494824 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 362.618727 +Last_query_cost 0.494824 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 362.618727 +Last_query_cost 0.453844 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 362.618727 +Last_query_cost 0.453844 set optimizer_prune_level=2; select @@optimizer_prune_level; @@optimizer_prune_level @@ -439,7 +439,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 1.650935 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 @@ -451,87 +451,87 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 1.650935 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.602062 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.602062 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) -show status like 'Last_query_cost'; -Variable_name Value -Last_query_cost 844.037037 -explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.621783 +explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) +show status like 'Last_query_cost'; +Variable_name Value +Last_query_cost 0.621783 set optimizer_search_depth=1; select @@optimizer_search_depth; @@optimizer_search_depth 1 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t7 index PRIMARY PRIMARY 4 NULL 21 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 34.291074 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t7 index PRIMARY PRIMARY 4 NULL 21 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.c22 1 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.c42 1 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 34.291074 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index +1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 9 Using index +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) @@ -539,19 +539,19 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 14.789792 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where +1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 9 Using index +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 14.789792 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where @@ -563,7 +563,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 1.698747 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where @@ -575,7 +575,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 1.698747 set optimizer_search_depth=62; select @@optimizer_search_depth; @@optimizer_search_depth @@ -591,7 +591,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 1.650935 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 @@ -603,55 +603,55 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 1693.637037 +Last_query_cost 1.650935 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.602062 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.602062 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) -show status like 'Last_query_cost'; -Variable_name Value -Last_query_cost 844.037037 -explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 844.037037 +Last_query_cost 0.621783 +explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.c21 1 Using where +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) +show status like 'Last_query_cost'; +Variable_name Value +Last_query_cost 0.621783 drop table t1,t2,t3,t4,t5,t6,t7; CREATE TABLE t1 (a int, b int, d int, i int); INSERT INTO t1 VALUES (1,1,1,1); @@ -802,6 +802,9 @@ WHERE t100.K=t10.I AND t10000.K=t10.I; COUNT(*) 9 +##### +# Expect all variants of EQ joining t100 & t10000 with T10 +# to have same cost # handler_reads: flush status; EXPLAIN SELECT COUNT(*) FROM t10,t100,t10000 WHERE t100.K=t10.I @@ -909,6 +912,12 @@ AND t10000.K=t10.K; COUNT(*) 9 ### NOTE: Handler_reads: 31, expected: 30 ### +##### +## EQ_REF Should be executed before table scan(ALL) +## - Independent of #records in table being EQ_REF-joined +##### +##### +# Expect: Join EQ_REF(t100) before ALL(t10000) flush status; EXPLAIN SELECT STRAIGHT_JOIN COUNT(*) FROM t10,t100,t10000 WHERE t100.K=t10.I @@ -948,6 +957,8 @@ WHERE t100.K=t10.I AND t10000.I=t10.I; COUNT(*) 9000 +##### +# Expect: Join EQ_REF(t10000) before ALL(t100) (star-join) flush status; EXPLAIN SELECT STRAIGHT_JOIN COUNT(*) FROM t10,t10000,t100 WHERE t100.I=t10.I @@ -1184,13 +1195,13 @@ COUNT(*) 9000 ### NOTE: Handler_reads: 9030, expected: 9045 ### flush status; -EXPLAIN SELECT STRAIGHT_JOIN COUNT(*) FROM t10,t10000 x,t10000 y +EXPLAIN SELECT STRAIGHT_JOIN COUNT(*) FROM t10000 y, t10, t10000 x WHERE x.k=t10.i; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t10 index IX IX 5 NULL 10 Using where; Using index +1 SIMPLE y index NULL PRIMARY 4 NULL 10000 Using index +1 SIMPLE t10 range IX IX 5 NULL 10 Using where; Using index; Using join buffer (flat, BNL join) 1 SIMPLE x eq_ref PRIMARY PRIMARY 4 test.t10.I 1 Using index -1 SIMPLE y index NULL PRIMARY 4 NULL 10000 Using index; Using join buffer (flat, BNL join) -SELECT STRAIGHT_JOIN COUNT(*) FROM t10,t10000 x,t10000 y +SELECT STRAIGHT_JOIN COUNT(*) FROM t10000 y, t10, t10000 x WHERE x.k=t10.i; COUNT(*) 90000 @@ -1198,9 +1209,9 @@ flush status; EXPLAIN SELECT COUNT(*) FROM t10,t10000 x,t10000 y WHERE x.k=t10.i; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t10 index IX IX 5 NULL 10 Using where; Using index +1 SIMPLE y index NULL PRIMARY 4 NULL 10000 Using index +1 SIMPLE t10 range IX IX 5 NULL 10 Using where; Using index; Using join buffer (flat, BNL join) 1 SIMPLE x eq_ref PRIMARY PRIMARY 4 test.t10.I 1 Using index -1 SIMPLE y index NULL PRIMARY 4 NULL 10000 Using index; Using join buffer (flat, BNL join) SELECT COUNT(*) FROM t10,t10000 x,t10000 y WHERE x.k=t10.i; COUNT(*) @@ -1209,9 +1220,9 @@ flush status; EXPLAIN SELECT COUNT(*) FROM t10,t10000 y,t10000 x WHERE x.k=t10.i; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t10 index IX IX 5 NULL 10 Using where; Using index +1 SIMPLE y index NULL PRIMARY 4 NULL 10000 Using index +1 SIMPLE t10 range IX IX 5 NULL 10 Using where; Using index; Using join buffer (flat, BNL join) 1 SIMPLE x eq_ref PRIMARY PRIMARY 4 test.t10.I 1 Using index -1 SIMPLE y index NULL PRIMARY 4 NULL 10000 Using index; Using join buffer (flat, BNL join) SELECT COUNT(*) FROM t10,t10000 y,t10000 x WHERE x.k=t10.i; COUNT(*) @@ -2902,7 +2913,7 @@ EXPLAIN SELECT COUNT(*) FROM t1 AS x JOIN t1 ON t1.K=x.I JOIN t2 ON t2.K=x.I JOI DROP TABLE t100, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33, t34, t35, t36, t37, t38, t39, t40, t41, t42, t43, t44, t45, t46, t47, t48, t49, t50, t51, t52, t53, t54, t55, t56, t57, t58, t59, t60, t61; show status like "optimizer%"; Variable_name Value -Optimizer_join_prefixes_check_calls 57916 +Optimizer_join_prefixes_check_calls 63164 SET OPTIMIZER_SEARCH_DEPTH = DEFAULT; # # Bug found when testing greedy optimizer tests @@ -2917,8 +2928,8 @@ explain SELECT * FROM t1 AS alias1 WHERE alias1.col_varchar_key IN (SELECT COUNT(*) FROM t1 AS SQ3_alias2 JOIN t1 AS SQ3_alias3 ON (SQ3_alias3.col_varchar_key = SQ3_alias2.col_varchar_key AND SQ3_alias3.pk = SQ3_alias2.pk)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY alias1 index NULL col_varchar_key 20 NULL 2 Using where; Using index -2 DEPENDENT SUBQUERY SQ3_alias2 index PRIMARY,col_varchar_key col_varchar_key 20 NULL 2 Using index -2 DEPENDENT SUBQUERY SQ3_alias3 eq_ref PRIMARY,col_varchar_key PRIMARY 4 test.SQ3_alias2.pk 1 Using where +2 DEPENDENT SUBQUERY SQ3_alias2 index PRIMARY,col_varchar_key col_varchar_key 20 NULL 2 Using where; Using index +2 DEPENDENT SUBQUERY SQ3_alias3 ref PRIMARY,col_varchar_key col_varchar_key 11 test.SQ3_alias2.col_varchar_key 1 Using where; Using index drop table t1; # # This triggered an assert failure while testing diff --git a/mysql-test/main/greedy_optimizer.test b/mysql-test/main/greedy_optimizer.test index 2a830c70677..04f765e815a 100644 --- a/mysql-test/main/greedy_optimizer.test +++ b/mysql-test/main/greedy_optimizer.test @@ -441,9 +441,9 @@ WHERE t100.K=t10.I AND t10000.K=t10.I; --source include/check_qep.inc -##### -# Expect all variants of EQ joining t100 & t10000 with T10 -# to have same cost # handler_reads: +--echo ##### +--echo # Expect all variants of EQ joining t100 & t10000 with T10 +--echo # to have same cost # handler_reads: let $query= SELECT COUNT(*) FROM t10,t100,t10000 WHERE t100.K=t10.I @@ -493,12 +493,12 @@ WHERE t100.K=t10.I --source include/check_qep.inc -##### -## EQ_REF Should be executed before table scan(ALL) -## - Independent of #records in table being EQ_REF-joined -##### -##### -# Expect: Join EQ_REF(t100) before ALL(t10000) +--echo ##### +--echo ## EQ_REF Should be executed before table scan(ALL) +--echo ## - Independent of #records in table being EQ_REF-joined +--echo ##### +--echo ##### +--echo # Expect: Join EQ_REF(t100) before ALL(t10000) let $query= SELECT STRAIGHT_JOIN COUNT(*) FROM t10,t100,t10000 WHERE t100.K=t10.I @@ -517,8 +517,8 @@ WHERE t100.K=t10.I AND t10000.I=t10.I; --source include/check_qep.inc -##### -# Expect: Join EQ_REF(t10000) before ALL(t100) (star-join) +--echo ##### +--echo # Expect: Join EQ_REF(t10000) before ALL(t100) (star-join) let $query= SELECT STRAIGHT_JOIN COUNT(*) FROM t10,t10000,t100 WHERE t100.I=t10.I @@ -662,7 +662,7 @@ WHERE t100.K=t10.I ## Expect this QEP, cost & #handler_read # Expected QEP: 'join EQ_REF(X) on X.K=t10.I' before 'cross' ALL(Y) let $query= -SELECT STRAIGHT_JOIN COUNT(*) FROM t10,t10000 x,t10000 y +SELECT STRAIGHT_JOIN COUNT(*) FROM t10000 y, t10, t10000 x WHERE x.k=t10.i; --source include/expect_qep.inc diff --git a/mysql-test/main/group_by.result b/mysql-test/main/group_by.result index ba403fa8b73..ef5e500c314 100644 --- a/mysql-test/main/group_by.result +++ b/mysql-test/main/group_by.result @@ -552,12 +552,12 @@ a b 3 1 explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL a NULL NULL NULL 4 Using temporary; Using filesort -1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort +1 SIMPLE t2 ref a a 4 test.t1.a 1 explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL a NULL NULL NULL 4 Using temporary -1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary +1 SIMPLE t2 ref a a 4 test.t1.a 1 drop table t1,t2; SET @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity,@@optimizer_switch=@save_optimizer_switch; create table t1 (a int, b int); @@ -890,7 +890,8 @@ Level Code Message drop table t1, t2; CREATE TABLE t1 (a tinyint(3), b varchar(255), PRIMARY KEY (a)); INSERT INTO t1 VALUES (1,'-----'), (6,'Allemagne'), (17,'Autriche'), -(25,'Belgique'), (54,'Danemark'), (62,'Espagne'), (68,'France'); +(25,'Belgique'), (54,'Danemark'), (62,'Espagne'), (68,'France'), +(100,"No land"), (101,"No land"); CREATE TABLE t2 (a tinyint(3), b tinyint(3), PRIMARY KEY (a), KEY b (b)); INSERT INTO t2 VALUES (1,1), (2,1), (6,6), (18,17), (15,25), (16,25), (17,25), (10,54), (5,62),(3,68); @@ -1352,7 +1353,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY,i2 PRIMARY 4 NULL 1 Using where; Using index EXPLAIN SELECT a FROM t1 WHERE a < 2 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,i2 PRIMARY 4 NULL 1 Using where; Using index +1 SIMPLE t1 range PRIMARY,i2 i2 4 NULL 1 Using where; Using index for group-by EXPLAIN SELECT a FROM t1 IGNORE INDEX (PRIMARY,i2); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 144 @@ -1578,7 +1579,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT a FROM t1 FORCE INDEX FOR JOIN (i2) FORCE INDEX FOR GROUP BY (i2) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL i2 4 NULL 145 Using index for group-by +1 SIMPLE t1 index NULL i2 9 NULL 144 Using index EXPLAIN SELECT a FROM t1 USE INDEX () IGNORE INDEX (i2); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 144 @@ -1701,7 +1702,7 @@ NULL 1 1 2 EXPLAIN SELECT a from t2 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL a 5 NULL 7 Using index for group-by +1 SIMPLE t2 range NULL a 5 NULL 6 Using index for group-by SELECT a from t2 GROUP BY a; a NULL @@ -1714,6 +1715,18 @@ b NULL 1 2 +insert into t2 SELECT NULL, NULL from seq_1_to_10; +EXPLAIN SELECT b from t2 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range NULL a 5 NULL 9 Using index for group-by +# Expect: Using index for group-by +analyze table t2; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +EXPLAIN SELECT b from t2 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range NULL a 5 NULL 6 Using index for group-by DROP TABLE t1; DROP TABLE t2; CREATE TABLE t1 ( a INT, b INT ); @@ -1959,8 +1972,8 @@ SELECT a, AVG(t1.b), FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 10 NULL 9 Using index -3 DEPENDENT SUBQUERY t12 ref a a 10 func,func 2 Using index condition -2 DEPENDENT SUBQUERY t11 ref a a 10 func,func 2 Using index condition +3 DEPENDENT SUBQUERY t12 ref a a 10 func,func 1 Using index condition +2 DEPENDENT SUBQUERY t11 ref a a 10 func,func 1 Using index condition SELECT a, AVG(t1.b), (SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c, (SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c @@ -2452,7 +2465,7 @@ test.t1 analyze status OK EXPLAIN SELECT SQL_BUFFER_RESULT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 9 NULL 2 Using where; Using index for group-by; Using temporary +1 SIMPLE t1 range b b 9 NULL 1 Using where; Using index for group-by; Using temporary SELECT SQL_BUFFER_RESULT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; MIN(a) b @@ -2460,7 +2473,7 @@ MIN(a) b EXPLAIN SELECT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 9 NULL 2 Using where; Using index for group-by +1 SIMPLE t1 range b b 9 NULL 1 Using where; Using index for group-by SELECT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; MIN(a) b @@ -2989,3 +3002,34 @@ drop table t20, t21, t22; # # End of 10.3 tests # +# +# Test new group_min_max optimization +# +create table t1 (a int, b int, c int, key(a,b,c)); +insert into t1 select mod(seq,23),mod(seq,13), mod(seq,5) from seq_1_to_10000; +explain select a from t1 where a in (1,2,3) group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index for group-by +explain select a from t1 where a in (1,2,3) or a = 22 group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index for group-by +explain select a from t1 where a in (1,2,3) and a < 3 group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index for group-by +explain select a,b from t1 where (a) in (1,2,3) and b in (5,6,7) group by a,b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 10 NULL 9 Using where; Using index for group-by +explain select a,b from t1 where (a,b) in ((1,1),(2,2),(3,3)) group by a,b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 10 NULL 3 Using where; Using index for group-by +explain select a,b,c from t1 where (a,b) in ((1,1),(2,2),(3,3)) and c=3 group by a,b,c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 15 NULL 3 Using where; Using index for group-by +# Will not use index for group-by +explain select a from t1 where a in (1,2,3) and b>1 group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 10 NULL 983 Using where; Using index +explain select a from t1 where a in (1,2,3) and c=1 group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 1161 Using where; Using index +drop table t1; diff --git a/mysql-test/main/group_by.test b/mysql-test/main/group_by.test index 357959d4071..3aa7f1cd0d3 100644 --- a/mysql-test/main/group_by.test +++ b/mysql-test/main/group_by.test @@ -1,3 +1,5 @@ +--source include/have_sequence.inc + # Initialise --disable_warnings drop table if exists t1,t2,t3; @@ -716,7 +718,8 @@ drop table t1, t2; CREATE TABLE t1 (a tinyint(3), b varchar(255), PRIMARY KEY (a)); INSERT INTO t1 VALUES (1,'-----'), (6,'Allemagne'), (17,'Autriche'), - (25,'Belgique'), (54,'Danemark'), (62,'Espagne'), (68,'France'); + (25,'Belgique'), (54,'Danemark'), (62,'Espagne'), (68,'France'), + (100,"No land"), (101,"No land"); CREATE TABLE t2 (a tinyint(3), b tinyint(3), PRIMARY KEY (a), KEY b (b)); @@ -1164,6 +1167,13 @@ SELECT a from t2 GROUP BY a; EXPLAIN SELECT b from t2 GROUP BY b; SELECT b from t2 GROUP BY b; +# Show that we are using 'range' when there is more NULL rows in the table +insert into t2 SELECT NULL, NULL from seq_1_to_10; +EXPLAIN SELECT b from t2 GROUP BY a; +--echo # Expect: Using index for group-by +analyze table t2; +EXPLAIN SELECT b from t2 GROUP BY a; + DROP TABLE t1; DROP TABLE t2; @@ -2124,3 +2134,22 @@ drop table t20, t21, t22; --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # Test new group_min_max optimization +--echo # + +create table t1 (a int, b int, c int, key(a,b,c)); +insert into t1 select mod(seq,23),mod(seq,13), mod(seq,5) from seq_1_to_10000; + +explain select a from t1 where a in (1,2,3) group by a; +explain select a from t1 where a in (1,2,3) or a = 22 group by a; +explain select a from t1 where a in (1,2,3) and a < 3 group by a; +explain select a,b from t1 where (a) in (1,2,3) and b in (5,6,7) group by a,b; +explain select a,b from t1 where (a,b) in ((1,1),(2,2),(3,3)) group by a,b; +explain select a,b,c from t1 where (a,b) in ((1,1),(2,2),(3,3)) and c=3 group by a,b,c; + +--echo # Will not use index for group-by +explain select a from t1 where a in (1,2,3) and b>1 group by a; +explain select a from t1 where a in (1,2,3) and c=1 group by a; +drop table t1; diff --git a/mysql-test/main/group_min_max.result b/mysql-test/main/group_min_max.result index 2b8b10b29b9..a227246e7ec 100644 --- a/mysql-test/main/group_min_max.result +++ b/mysql-test/main/group_min_max.result @@ -2230,10 +2230,10 @@ a BB EXPLAIN SELECT a FROM t1 WHERE a='AA' GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref PRIMARY PRIMARY 7 const 4 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 7 NULL 1 Using where; Using index for group-by EXPLAIN SELECT a FROM t1 WHERE a='BB' GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref PRIMARY PRIMARY 7 const 1 Using where; Using index +1 SIMPLE t1 range PRIMARY PRIMARY 7 NULL 1 Using where; Using index for group-by SELECT DISTINCT a FROM t1 WHERE a='BB'; a BB @@ -2353,6 +2353,9 @@ t1; id2 id3 id5 id4 id3 id6 id5 id1 1 1 1 1 1 1 1 1 DROP TABLE t1,t2,t3,t4,t5,t6; +# +# Bug#22342: No results returned for query using max and group by +# CREATE TABLE t1 (a int, b int, KEY (a,b), KEY b (b)); INSERT INTO t1 VALUES (1,1),(1,2),(1,0),(1,3), @@ -2361,20 +2364,31 @@ ANALYZE TABLE t1; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK +CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a,b,c)); +INSERT INTO t2 SELECT a,b,b FROM t1; explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a,b a 10 NULL 2 Using where; Using index for group-by +1 SIMPLE t1 range a,b a 10 NULL 1 Using where; Using index for group-by +insert into t1 select 1,seq from seq_1_to_100; +explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a,b a 10 NULL 1 Using where; Using index for group-by +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a,b a 10 NULL 1 Using where; Using index for group-by SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; MAX(b) a 1 1 SELECT MIN(b), a FROM t1 WHERE b > 1 AND a = 1 GROUP BY a; MIN(b) a 2 1 -CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a,b,c)); -INSERT INTO t2 SELECT a,b,b FROM t1; explain SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range PRIMARY PRIMARY 12 NULL 1 Using where; Using index +1 SIMPLE t2 range PRIMARY PRIMARY 12 NULL 1 Using where; Using index for group-by SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a; MIN(c) 2 @@ -2446,7 +2460,7 @@ EXPLAIN SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x FROM t1 AS t1_outer; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer index NULL a 10 NULL 15 Using index -2 SUBQUERY t1 range a a 5 NULL 5 Using where; Using index +2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE EXISTS (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra @@ -2456,31 +2470,31 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t1 range a a 5 NULL 5 Using where; Using index +2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1_outer index a a 10 NULL 15 Using where; Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1_outer.a 1 -2 MATERIALIZED t1 range a a 5 NULL 5 Using where; Using index +1 PRIMARY ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t1_outer ref a a 5 .max(b) 3 Using index +2 MATERIALIZED t1 range a a 5 NULL 2 Using where; Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer range NULL a 5 NULL 6 Using index for group-by -2 SUBQUERY t1 range a a 5 NULL 5 Using where; Using index +2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer1 JOIN t1 AS t1_outer2 ON t1_outer1.a = (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) AND t1_outer1.b = t1_outer2.b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index 1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join) -2 SUBQUERY t1 range a a 5 NULL 5 Using where; Using index +2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index for group-by EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using index 2 SUBQUERY t1_outer index NULL a 10 NULL 15 Using index -3 SUBQUERY t1 range a a 5 NULL 5 Using where; Using index +3 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index for group-by CREATE TABLE t3 LIKE t1; FLUSH STATUS; INSERT INTO t3 SELECT a,MAX(b) FROM t1 GROUP BY a; @@ -2664,7 +2678,7 @@ a b 3 13 explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range a,index a 5 NULL 3 100.00 Using where; Using index for group-by; Using temporary +1 SIMPLE t1 range a,index a 5 NULL 1 100.00 Using where; Using index for group-by; Using temporary Warnings: Note 1003 select sql_buffer_result `test`.`t1`.`a` AS `a`,max(`test`.`t1`.`b`) + 1 AS `max(b)+1` from `test`.`t1` where `test`.`t1`.`a` = 0 group by `test`.`t1`.`a` drop table t1; @@ -3565,7 +3579,7 @@ a c COUNT(DISTINCT c, a, b) EXPLAIN SELECT COUNT(DISTINCT c, a, b) FROM t2 WHERE a > 5 AND b BETWEEN 10 AND 20 GROUP BY a, b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 5 NULL 1 Using where; Using index +1 SIMPLE t2 range a a 15 NULL 1 Using where; Using index for group-by SELECT COUNT(DISTINCT c, a, b) FROM t2 WHERE a > 5 AND b BETWEEN 10 AND 20 GROUP BY a, b, c; COUNT(DISTINCT c, a, b) @@ -3657,14 +3671,34 @@ KEY (f1,f2) ) ; insert into t1 values(1,'A'),(1 , 'B'), (1, 'C'), (2, 'A'), (3, 'A'), (3, 'B'), (3, 'C'), (3, 'D'); +explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL f1 5 NULL 8 Using index for group-by SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; f1 COUNT(DISTINCT f2) 1 3 2 1 3 4 +insert into t1 select seq/10,char(64+mod(seq,4)) from seq_1_to_100; explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL f1 5 NULL 9 Using index for group-by +1 SIMPLE t1 range NULL f1 5 NULL 10 Using index for group-by +SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; +f1 COUNT(DISTINCT f2) +0 4 +1 4 +2 4 +3 5 +4 4 +5 4 +6 4 +7 4 +8 4 +9 4 +10 4 +explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL f1 5 NULL 10 Using index for group-by drop table t1; # End of test#50539. # @@ -4092,7 +4126,7 @@ CREATE TABLE t1 (p int NOT NULL, a int NOT NULL, PRIMARY KEY (p,a)); insert into t1 select 2,seq from seq_0_to_1000; EXPLAIN select MIN(a) from t1 where p = 2 group by p; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 10 Using where; Using index for group-by +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using index for group-by SELECT MIN(a) from t1 where p = 2 group by p; MIN(a) 0 diff --git a/mysql-test/main/group_min_max.test b/mysql-test/main/group_min_max.test index 0fa91e4d72b..d230cd15749 100644 --- a/mysql-test/main/group_min_max.test +++ b/mysql-test/main/group_min_max.test @@ -899,23 +899,27 @@ t1; DROP TABLE t1,t2,t3,t4,t5,t6; -# -# Bug#22342: No results returned for query using max and group by -# +--echo # +--echo # Bug#22342: No results returned for query using max and group by +--echo # CREATE TABLE t1 (a int, b int, KEY (a,b), KEY b (b)); INSERT INTO t1 VALUES (1,1),(1,2),(1,0),(1,3), (1,-1),(1,-2),(1,-3),(1,-4); ANALYZE TABLE t1; - -explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; -SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; -SELECT MIN(b), a FROM t1 WHERE b > 1 AND a = 1 GROUP BY a; CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a,b,c)); INSERT INTO t2 SELECT a,b,b FROM t1; + +explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; +insert into t1 select 1,seq from seq_1_to_100; +explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; +analyze table t1; +explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; + +SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a; +SELECT MIN(b), a FROM t1 WHERE b > 1 AND a = 1 GROUP BY a; explain SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a; SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a; - DROP TABLE t1,t2; # @@ -1388,6 +1392,7 @@ SELECT a, c, COUNT(DISTINCT c, a, b) FROM t2 GROUP BY a, b, c; EXPLAIN SELECT COUNT(DISTINCT c, a, b) FROM t2 WHERE a > 5 AND b BETWEEN 10 AND 20 GROUP BY a, b, c; + SELECT COUNT(DISTINCT c, a, b) FROM t2 WHERE a > 5 AND b BETWEEN 10 AND 20 GROUP BY a, b, c; @@ -1439,10 +1444,12 @@ CREATE TABLE t1 ( ) ; insert into t1 values(1,'A'),(1 , 'B'), (1, 'C'), (2, 'A'), (3, 'A'), (3, 'B'), (3, 'C'), (3, 'D'); - +explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; +SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; +insert into t1 select seq/10,char(64+mod(seq,4)) from seq_1_to_100; +explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1; - drop table t1; --echo # End of test#50539. diff --git a/mysql-test/main/group_min_max_innodb.result b/mysql-test/main/group_min_max_innodb.result index 3586ad5237f..2b42ac1cbe1 100644 --- a/mysql-test/main/group_min_max_innodb.result +++ b/mysql-test/main/group_min_max_innodb.result @@ -73,10 +73,10 @@ insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d"); alter table t1 drop primary key, add primary key (f2, f1); explain select distinct f1 a, f1 b from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary explain select distinct f1, f2 from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 drop table t1; create table t1(pk int primary key) engine=innodb; create view v1 as select pk from t1 where pk < 20; @@ -108,7 +108,7 @@ CREATE TABLE t1 (a CHAR(1), b CHAR(1), PRIMARY KEY (a,b)) ENGINE=InnoDB; INSERT INTO t1 VALUES ('a', 'b'), ('c', 'd'); EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 2 NULL 2 Using where; Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b'; COUNT(DISTINCT a) 1 @@ -118,7 +118,7 @@ ENGINE=InnoDB; INSERT INTO t1 VALUES ('a', 'b'), ('c', 'd'); EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 2 NULL 2 Using where; Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b'; COUNT(DISTINCT a) 1 @@ -162,7 +162,7 @@ ANALYZE TABLE t2; EXPLAIN SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' AND i2 = 17) OR ( c1 = 'F') GROUP BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range k1 k1 5 NULL 31 Using where; Using index +1 SIMPLE t1 range k1 k1 5 NULL 31 Using where SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' AND i2 = 17) OR ( c1 = 'F') GROUP BY c1; c1 max(i2) @@ -171,7 +171,7 @@ F 30 EXPLAIN SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR ( c1 = 'F' AND i2 = 17)) GROUP BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range k1 k1 5 NULL 31 Using where; Using index +1 SIMPLE t1 range k1 k1 5 NULL 31 Using where SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR ( c1 = 'F' AND i2 = 17)) GROUP BY c1; c1 max(i2) @@ -180,7 +180,7 @@ F 17 EXPLAIN SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR c1 = 'F' ) AND ( i2 = 17 ) GROUP BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range k1 k1 5 NULL 1 Using where; Using index for group-by +1 SIMPLE t1 range k1 k1 5 NULL 2 Using where SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR c1 = 'F' ) AND ( i2 = 17 ) GROUP BY c1; c1 max(i2) @@ -190,7 +190,7 @@ EXPLAIN SELECT c1, max(i2) FROM t1 WHERE ((c1 = 'C' AND (i2 = 40 OR i2 = 30)) OR ( c1 = 'F' AND (i2 = 40 ))) GROUP BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range k1 k1 5 NULL 3 Using where; Using index +1 SIMPLE t1 range k1 k1 5 NULL 3 Using where SELECT c1, max(i2) FROM t1 WHERE ((c1 = 'C' AND (i2 = 40 OR i2 = 30)) OR ( c1 = 'F' AND (i2 = 40 ))) GROUP BY c1; @@ -200,7 +200,7 @@ EXPLAIN SELECT c1, i1, max(i2) FROM t2 WHERE (c1 = 'C' OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 ) GROUP BY c1,i1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range k2 k2 9 NULL 60 Using where; Using index for group-by +1 SIMPLE t2 range k2 k2 5 NULL 60 Using where SELECT c1, i1, max(i2) FROM t2 WHERE (c1 = 'C' OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 ) GROUP BY c1,i1; @@ -211,7 +211,7 @@ EXPLAIN SELECT c1, i1, max(i2) FROM t2 WHERE (((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 )) GROUP BY c1,i1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range k2 k2 9 NULL 60 Using where; Using index for group-by +1 SIMPLE t2 range k2 k2 5 NULL 60 Using where SELECT c1, i1, max(i2) FROM t2 WHERE (((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 )) GROUP BY c1,i1; @@ -222,7 +222,7 @@ EXPLAIN SELECT c1, i1, max(i2) FROM t2 WHERE ((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35) OR ( i2 = 17 )) GROUP BY c1,i1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index k2 k2 9 NULL 180 Using where; Using index +1 SIMPLE t2 index k2 k2 9 NULL 180 Using where SELECT c1, i1, max(i2) FROM t2 WHERE ((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35) OR ( i2 = 17 )) GROUP BY c1,i1; diff --git a/mysql-test/main/having_cond_pushdown.result b/mysql-test/main/having_cond_pushdown.result index 59388aa7ca0..e1f49b075b7 100644 --- a/mysql-test/main/having_cond_pushdown.result +++ b/mysql-test/main/having_cond_pushdown.result @@ -34,6 +34,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -42,7 +43,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2" } @@ -60,6 +63,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -68,7 +72,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2" } @@ -105,12 +111,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2" } @@ -126,12 +135,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2" } @@ -168,6 +180,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -176,7 +189,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a < 4" } @@ -194,6 +209,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -202,7 +218,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a < 4" } @@ -243,6 +261,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -251,7 +270,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 or t1.a = 3" } @@ -271,6 +292,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -279,7 +301,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 or t1.a = 3" } @@ -319,6 +343,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a > 2 and max(t1.b) > 13 or t1.a < 3 and min(t1.c) > 1", "filesort": { "sort_key": "t1.a", @@ -328,7 +353,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2 or t1.a < 3" } @@ -347,6 +374,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a > 2 and max(t1.b) > 13 or t1.a < 3 and min(t1.c) > 1", "filesort": { "sort_key": "t1.a", @@ -356,7 +384,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2 or t1.a < 3" } @@ -393,6 +423,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.a) < 3", "filesort": { "sort_key": "t1.a", @@ -402,7 +433,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -421,6 +454,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.a) < 3", "filesort": { "sort_key": "t1.a", @@ -430,7 +464,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -466,6 +502,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) > 13", "filesort": { "sort_key": "t1.a", @@ -475,7 +512,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -494,6 +533,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) > 13", "filesort": { "sort_key": "t1.a", @@ -503,7 +543,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -539,13 +581,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.a) = 3", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 3" } @@ -562,13 +607,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.a) = 3", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 3" } @@ -602,13 +650,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) > 12", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2" } @@ -625,13 +676,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) > 12", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2" } @@ -665,6 +719,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) = 13", "filesort": { "sort_key": "t1.a", @@ -674,7 +729,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -693,6 +750,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) = 13", "filesort": { "sort_key": "t1.a", @@ -702,7 +760,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -740,6 +800,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "min(t1.c) < 3", "filesort": { "sort_key": "t1.a", @@ -749,7 +810,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -768,6 +831,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "min(t1.c) < 3", "filesort": { "sort_key": "t1.a", @@ -777,7 +841,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -813,13 +879,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) = 13 and min(t1.c) = 2", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2" } @@ -836,13 +905,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) = 13 and min(t1.c) = 2", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2" } @@ -877,6 +949,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a = test.f1()", "filesort": { "sort_key": "t1.a", @@ -886,7 +959,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -905,6 +980,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a = test.f1()", "filesort": { "sort_key": "t1.a", @@ -914,7 +990,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -948,7 +1026,7 @@ GROUP BY v1.a HAVING (v1.a>1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort -1 PRIMARY ref key0 key0 5 test.t2.x 2 +1 PRIMARY ref key0 key0 5 test.t2.x 1 2 DERIVED t1 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort explain format=json SELECT v1.a FROM t2,v1 @@ -959,6 +1037,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.a", "temporary_table": { @@ -967,7 +1046,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x > 1 and t2.x is not null" } @@ -981,11 +1062,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.x"], - "rows": 2, + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -994,7 +1078,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -1019,6 +1105,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.a", "temporary_table": { @@ -1027,7 +1114,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x > 1 and t2.x is not null" } @@ -1041,11 +1130,14 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.x"], - "rows": 2, + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1054,7 +1146,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -1095,7 +1189,7 @@ GROUP BY v1.c HAVING (v1.c>2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort -1 PRIMARY ref key0 key0 5 test.t2.x 2 Using where +1 PRIMARY ref key0 key0 5 test.t2.x 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort explain format=json SELECT v1.a,v1.c FROM t2,v1 @@ -1106,6 +1200,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.c", "temporary_table": { @@ -1114,7 +1209,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x is not null" } @@ -1128,12 +1225,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.x"], - "rows": 2, + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 2", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "t1.c > 2", "filesort": { "sort_key": "t1.a", @@ -1143,7 +1243,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1167,6 +1269,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "v1.c", "temporary_table": { @@ -1175,7 +1278,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x is not null" } @@ -1189,12 +1294,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.x"], - "rows": 2, + "loops": 4, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.c > 2", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "t1.c > 2", "filesort": { "sort_key": "t1.a", @@ -1204,7 +1312,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1256,6 +1366,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1264,7 +1375,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null" } @@ -1278,19 +1391,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["x", "MAX(t2.y)"], "ref": ["test.t1.a", "test.t1.b"], + "loops": 5, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x < 5 and t2.x > 1" } @@ -1315,6 +1433,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1323,7 +1442,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null" } @@ -1337,19 +1458,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["x", "MAX(t2.y)"], "ref": ["test.t1.a", "test.t1.b"], + "loops": 5, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x < 5 and t2.x > 1" } @@ -1399,6 +1525,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.b", "temporary_table": { @@ -1407,7 +1534,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b < 14 and t1.a is not null and t1.b is not null" } @@ -1421,12 +1550,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["x", "MAX(t2.y)"], "ref": ["test.t1.a", "test.t1.b"], + "loops": 5, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.y)` < 14", "temporary_table": { "nested_loop": [ @@ -1434,7 +1566,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x < 5" } @@ -1459,6 +1593,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.b", "temporary_table": { @@ -1467,7 +1602,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b < 14 and t1.a is not null and t1.b is not null" } @@ -1481,12 +1618,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["x", "MAX(t2.y)"], "ref": ["test.t1.a", "test.t1.b"], + "loops": 5, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.y)` < 14", "temporary_table": { "nested_loop": [ @@ -1494,7 +1634,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.x < 5" } @@ -1538,6 +1680,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.c = 2", "filesort": { "sort_key": "t1.a", @@ -1547,7 +1690,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -1565,6 +1710,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.c = 2", "filesort": { "sort_key": "t1.a", @@ -1574,7 +1720,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1" } @@ -1610,13 +1758,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a = 2 and t1.c = 2", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 13" } @@ -1633,13 +1784,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a = 2 and t1.c = 2", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 13" } @@ -1674,6 +1828,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1682,7 +1837,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and t1.a > 1" } @@ -1699,6 +1856,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1707,7 +1865,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and t1.a > 1" } @@ -1743,12 +1903,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2 and t1.c = 2" } @@ -1764,12 +1927,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2 and t1.c = 2" } @@ -1803,6 +1969,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.c = t1.a and t1.a > 1 or t1.a < 3 and t1.c > 3", "filesort": { "sort_key": "t1.a", @@ -1812,7 +1979,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and t1.a > 1 or t1.a < 3" } @@ -1831,6 +2000,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.c = t1.a and t1.a > 1 or t1.a < 3 and t1.c > 3", "filesort": { "sort_key": "t1.a", @@ -1840,7 +2010,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and t1.a > 1 or t1.a < 3" } @@ -1883,6 +2055,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1891,7 +2064,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and t1.a < 3" } @@ -1909,6 +2084,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1917,7 +2093,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and t1.a < 3" } @@ -1958,6 +2136,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1966,7 +2145,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and t1.a > 1 and t1.a < 3" } @@ -1984,6 +2165,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -1992,7 +2174,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and t1.a > 1 and t1.a < 3" } @@ -2032,6 +2216,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a > 1 and max(t1.c) < 3 or t1.c < 4", "filesort": { "sort_key": "t1.a", @@ -2041,7 +2226,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and (t1.a > 1 or t1.a < 4) and t1.a < 2" } @@ -2060,6 +2247,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a > 1 and max(t1.c) < 3 or t1.c < 4", "filesort": { "sort_key": "t1.a", @@ -2069,7 +2257,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and (t1.a > 1 or t1.a < 4) and t1.a < 2" } @@ -2112,6 +2302,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a > 1 and max(t1.c) < 3 or t1.c < 4", "filesort": { "sort_key": "t1.a", @@ -2121,7 +2312,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and (t1.a > 1 or t1.a < 4)" } @@ -2140,6 +2333,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a > 1 and max(t1.c) < 3 or t1.c < 4", "filesort": { "sort_key": "t1.a", @@ -2149,7 +2343,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = t1.a and (t1.a > 1 or t1.a < 4)" } @@ -2208,6 +2404,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.b = 13 and max(t1.c) > 2", "filesort": { "sort_key": "t1.a", @@ -2217,7 +2414,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2234,6 +2433,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.b = 13 and max(t1.c) > 2", "filesort": { "sort_key": "t1.a", @@ -2243,7 +2443,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2281,6 +2483,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2289,7 +2492,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 1 or t1.b > 10) and t1.b < 14" } @@ -2307,6 +2512,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2315,7 +2521,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 1 or t1.b > 10) and t1.b < 14" } @@ -2355,6 +2563,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2363,7 +2572,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 1 or t1.b > 10) and (t1.b < 14 or t1.b > 15)" } @@ -2381,6 +2592,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2389,7 +2601,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 1 or t1.b > 10) and (t1.b < 14 or t1.b > 15)" } @@ -2428,6 +2642,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2436,7 +2651,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 1 or t1.b > 10) and (t1.b < 14 or t1.a = 2 and t1.b > 15)" } @@ -2454,6 +2671,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2462,7 +2680,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 1 or t1.b > 10) and (t1.b < 14 or t1.a = 2 and t1.b > 15)" } @@ -2503,6 +2723,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2511,7 +2732,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2 or t1.b = 13 and t1.a > 2" } @@ -2529,6 +2752,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2537,7 +2761,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2 or t1.b = 13 and t1.a > 2" } @@ -2575,6 +2801,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2583,7 +2810,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 14 and t1.a < 2 or t1.b = 13 and t1.a > 2" } @@ -2601,6 +2830,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2609,7 +2839,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 14 and t1.a < 2 or t1.b = 13 and t1.a > 2" } @@ -2649,6 +2881,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2657,7 +2890,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 14 and t1.a < 2 or t1.a > 2 and (t1.b = 13 or t1.b = 14)" } @@ -2675,6 +2910,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -2683,7 +2919,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 14 and t1.a < 2 or t1.a > 2 and (t1.b = 13 or t1.b = 14)" } @@ -2719,6 +2957,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a < 2 and max(t1.c) = 2 or max(t1.c) > 2 and (t1.a = 1 or t1.a = 2)", "filesort": { "sort_key": "t1.a", @@ -2728,7 +2967,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2 or t1.a = 1 or t1.a = 2" } @@ -2747,6 +2988,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a < 2 and max(t1.c) = 2 or max(t1.c) > 2 and (t1.a = 1 or t1.a = 2)", "filesort": { "sort_key": "t1.a", @@ -2756,7 +2998,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2 or t1.a = 1 or t1.a = 2" } @@ -2794,6 +3038,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a = 2 and max(t1.c) = 2 or max(t1.c) > 2 and (t1.a = 1 or t1.a = 2)", "filesort": { "sort_key": "t1.a", @@ -2803,7 +3048,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2 or t1.a = 1 or t1.a = 2" } @@ -2822,6 +3069,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.a = 2 and max(t1.c) = 2 or max(t1.c) > 2 and (t1.a = 1 or t1.a = 2)", "filesort": { "sort_key": "t1.a", @@ -2831,7 +3079,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 2 or t1.a = 1 or t1.a = 2" } @@ -2868,13 +3118,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.c) = 3", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -2891,13 +3144,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.c) = 3", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -2932,13 +3188,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b = 14)", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 3" } @@ -2955,13 +3214,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) = 14", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 3" } @@ -2995,13 +3257,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b = 14)", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 1" } @@ -3018,13 +3283,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "max(t1.b) = 14", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 1" } @@ -3068,6 +3336,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3076,7 +3345,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 2 and t1.a < 3" } @@ -3094,6 +3365,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3102,7 +3374,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 2 and t1.a < 3" } @@ -3143,12 +3417,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 3 and t1.b > 2" } @@ -3164,12 +3441,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 3 and t1.b > 2" } @@ -3208,6 +3488,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3216,7 +3497,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 14 and t1.a < 3" } @@ -3234,6 +3517,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3242,7 +3526,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 14 and t1.a < 3" } @@ -3283,12 +3569,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.b = 14" } @@ -3304,12 +3593,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = 14 and t1.a = 1" } @@ -3395,12 +3687,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 1" } @@ -3416,12 +3711,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = 1 and t1.a = 1" } @@ -3462,6 +3760,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3470,7 +3769,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c > 0 and t1.c < 3 and t1.a > 1" } @@ -3488,6 +3789,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3496,7 +3798,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c > 0 and t1.c < 3 and t1.a > 1" } @@ -3537,12 +3841,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c > 0 and t1.c < 3" } @@ -3558,12 +3865,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c > 0 and t1.c < 3" } @@ -3602,13 +3912,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c < 3" } @@ -3624,12 +3937,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c < 3" } @@ -3713,12 +4029,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.b = 2 and t3.d = 1 and t3.a = 1" } @@ -3734,12 +4053,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.b = 2 and t3.d = 1 and t3.a = 1" } @@ -3778,6 +4100,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3786,7 +4109,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a > 1 or t1.c < 3) and t1.a < 2" } @@ -3804,6 +4129,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3812,7 +4138,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a > 1 or t1.c < 3) and t1.a < 2" } @@ -3901,6 +4229,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3909,7 +4238,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a < 4 and t1.a > 0" } @@ -3927,6 +4258,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -3935,7 +4267,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a < 4 and t1.a > 0" } @@ -3976,13 +4310,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1 and 1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -3998,12 +4335,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -4044,6 +4384,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -4052,7 +4393,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and (t1.a < 4 or t1.a > 0)" } @@ -4070,6 +4413,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -4078,7 +4422,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and (t1.a < 4 or t1.a > 0)" } @@ -4119,13 +4465,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -4141,12 +4490,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1" } @@ -4187,6 +4539,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.c > 1", "filesort": { "sort_key": "t1.a", @@ -4196,7 +4549,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.c < 3 and t1.a < 4" } @@ -4216,6 +4571,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.c > 1", "filesort": { "sort_key": "t1.a", @@ -4225,7 +4581,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.c < 3 and t1.a < 4" } @@ -4263,6 +4621,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "filesort": { "sort_key": "t1.c", @@ -4272,7 +4631,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c < 3 and t1.c > 1" } @@ -4291,6 +4652,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.c", "temporary_table": { @@ -4299,7 +4661,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c < 3 and t1.c > 1" } @@ -4339,13 +4703,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1 and 1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 3" } @@ -4362,12 +4729,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 3" } @@ -4405,13 +4775,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t3.d > 0", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.a = 1 and t3.d = 1 and t3.b = 2" } @@ -4429,13 +4802,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t3.d > 0", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.a = 1 and t3.d = 1 and t3.b = 2" } @@ -4473,13 +4849,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.a = 1 and t3.d = 1 and t3.b = 2" } @@ -4496,12 +4875,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.a = 1 and t3.d = 1 and t3.b = 2" } @@ -4542,6 +4924,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.c > 1", "filesort": { "sort_key": "t1.a", @@ -4551,7 +4934,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a > 1 or t1.c < 3) and t1.a < 4" } @@ -4571,6 +4956,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "t1.c > 1", "filesort": { "sort_key": "t1.a", @@ -4580,7 +4966,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a > 1 or t1.c < 3) and t1.a < 4" } @@ -4624,6 +5012,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.c", "temporary_table": { @@ -4632,7 +5021,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a > 1 or t1.c < 3) and t1.a < 4 and t1.c > 1" } @@ -4651,6 +5042,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.c", "temporary_table": { @@ -4659,7 +5051,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a > 1 or t1.c < 3) and t1.a < 4 and t1.c > 1" } @@ -4703,6 +5097,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.c", "temporary_table": { @@ -4711,7 +5106,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 1 or t1.a = 3) and (t1.a = 4 or t1.c > 1)" } @@ -4730,6 +5127,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.c", "temporary_table": { @@ -4738,7 +5136,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 1 or t1.a = 3) and (t1.a = 4 or t1.c > 1)" } @@ -4779,12 +5179,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 1" } @@ -4800,12 +5203,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 1" } @@ -4844,12 +5250,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 1" } @@ -4866,12 +5275,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.c = 1" } @@ -5051,6 +5463,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t3.a", "temporary_table": { @@ -5059,7 +5472,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.d = t3.a and t3.a > 1 and (t3.c = 3 or t3.c < 2) and (t3.a = 1 or t3.a > 1)" } @@ -5078,6 +5493,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t3.a", "temporary_table": { @@ -5086,7 +5502,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.d = t3.a and t3.a > 1 and (t3.c = 3 or t3.c < 2) and (t3.a = 1 or t3.a > 1)" } @@ -5125,6 +5543,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t3.a", "temporary_table": { @@ -5133,7 +5552,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.d = t3.a and t3.a > 1 and (t3.c = 3 or t3.c < 2) and (t3.c = t3.a and t3.c < 15 or t3.a > 1)" } @@ -5152,6 +5573,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t3.a", "temporary_table": { @@ -5160,7 +5582,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.d = t3.a and t3.a > 1 and (t3.c = 3 or t3.c < 2) and (t3.c = t3.a and t3.a < 15 or t3.a > 1)" } @@ -5240,6 +5664,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.d1", "temporary_table": { @@ -5248,7 +5673,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.d1 between (inet_aton('1978-04-27')) and ('2018-08-26')" } @@ -5282,6 +5709,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.d1", "temporary_table": { @@ -5290,7 +5718,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.d1 not between (0) and (exp(0))" } @@ -5357,6 +5787,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "temporary_table": { @@ -5365,7 +5796,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 8 or t1.a = (subquery#2)" } @@ -5375,12 +5808,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -5401,6 +5837,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a, t1.b", "temporary_table": { @@ -5409,7 +5846,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a = 8 or t1.a = (subquery#2)) and t1.b < 20" } @@ -5419,12 +5858,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -5445,6 +5887,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "sum(t1.b) > 20", "filesort": { "sort_key": "t1.a", @@ -5454,7 +5897,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 8 or t1.a = (subquery#2)" } @@ -5464,12 +5909,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -5490,12 +5938,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = (subquery#2)" } @@ -5505,12 +5956,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } diff --git a/mysql-test/main/having_cond_pushdown.test b/mysql-test/main/having_cond_pushdown.test index 99e4a597f22..be18699519e 100644 --- a/mysql-test/main/having_cond_pushdown.test +++ b/mysql-test/main/having_cond_pushdown.test @@ -23,12 +23,14 @@ HAVING (t1.a>2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) FROM t1 WHERE (t1.a>2) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : using equality @@ -40,12 +42,14 @@ HAVING (t1.a=2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) FROM t1 WHERE (t1.a=2) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # extracted AND formula @@ -57,12 +61,14 @@ HAVING (t1.a>1) AND (t1.a<4); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) FROM t1 WHERE (t1.a>1) AND (t1.a<4) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # extracted OR formula @@ -75,6 +81,7 @@ eval $no_pushdown $query; eval $query; --enable_prepare_warnings eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; --disable_prepare_warnings let $query= @@ -83,6 +90,7 @@ FROM t1 WHERE (t1.a>1) OR (a IN (SELECT 3)) GROUP BY t1.a; --enable_prepare_warnings +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --disable_prepare_warnings @@ -94,6 +102,7 @@ HAVING ((t1.a>2) AND (MAX(t1.b)>13)) OR ((t1.a<3) AND (MIN(t1.c)>1)); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -101,6 +110,7 @@ FROM t1 WHERE (t1.a>2) OR (t1.a<3) GROUP BY t1.a HAVING ((t1.a>2) AND (MAX(t1.b)>13)) OR ((t1.a<3) AND (MIN(t1.c)>1)); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : no aggregation formula pushdown @@ -112,6 +122,7 @@ HAVING (t1.a>1) AND (MAX(t1.a)<3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) @@ -119,6 +130,7 @@ FROM t1 WHERE (t1.a>1) GROUP BY t1.a HAVING (MAX(t1.a)<3); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -129,6 +141,7 @@ HAVING (t1.a>1) AND (MAX(t1.b)>13); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) @@ -136,6 +149,7 @@ FROM t1 WHERE (t1.a>1) GROUP BY t1.a HAVING (MAX(t1.b)>13); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -146,6 +160,7 @@ HAVING (t1.a=3) AND (MAX(t1.a)=3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) @@ -153,6 +168,7 @@ FROM t1 WHERE (t1.a=3) GROUP BY t1.a HAVING (MAX(t1.a)=3); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -163,6 +179,7 @@ HAVING (t1.a=2) AND (MAX(t1.b)>12); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) @@ -170,6 +187,7 @@ FROM t1 WHERE (t1.a=2) GROUP BY t1.a HAVING (MAX(t1.b)>12); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -180,6 +198,7 @@ HAVING (t1.a>1) AND (MAX(t1.b)=13); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) @@ -187,6 +206,7 @@ FROM t1 WHERE (t1.a>1) GROUP BY t1.a HAVING (MAX(t1.b)=13); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -197,6 +217,7 @@ HAVING (t1.a>1) AND (MIN(t1.c)<3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MIN(t1.c) @@ -204,6 +225,7 @@ FROM t1 WHERE (t1.a>1) GROUP BY t1.a HAVING (MIN(t1.c)<3); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -214,6 +236,7 @@ HAVING (t1.a=2) AND (MAX(t1.b)=13) AND (MIN(t1.c)=2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MIN(t1.c) @@ -221,6 +244,7 @@ FROM t1 WHERE (t1.a=2) GROUP BY t1.a HAVING (MAX(t1.b)=13) AND (MIN(t1.c)=2); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : no stored function pushdown @@ -232,6 +256,7 @@ HAVING (t1.a>1) AND (a=test.f1()); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) @@ -239,6 +264,7 @@ FROM t1 WHERE (t1.a>1) GROUP BY t1.a HAVING (a=test.f1()); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : pushdown into derived table WHERE clause @@ -251,12 +277,14 @@ HAVING (v1.a>1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT v1.a FROM t2,v1 WHERE (t2.x=v1.a) AND (v1.a>1) GROUP BY v1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : pushdown into derived table HAVING clause @@ -269,12 +297,14 @@ HAVING (v1.c>2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT v1.a,v1.c FROM t2,v1 WHERE (t2.x=v1.a) AND (v1.c>2) GROUP BY v1.c; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : pushdown into materialized IN subquery @@ -288,6 +318,7 @@ HAVING (t1.a>1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT * FROM t1 @@ -295,6 +326,7 @@ WHERE (t1.a>1) AND (t1.a,t1.b) IN (SELECT t2.x,MAX(t2.y) FROM t2 WHERE t2.x<5 GROUP BY t2.x) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : pushdown into materialized IN subquery @@ -308,6 +340,7 @@ HAVING (t1.b<14); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT * FROM t1 @@ -315,6 +348,7 @@ WHERE (t1.b<14) AND (t1.a,t1.b) IN (SELECT t2.x,MAX(t2.y) FROM t2 WHERE t2.x<5 GROUP BY t2.x) GROUP BY t1.b; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # non-standard allowed queries @@ -327,12 +361,14 @@ HAVING (t1.c=2) AND (t1.a>1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a>1) GROUP BY t1.a HAVING (t1.c=2); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -343,6 +379,7 @@ HAVING (t1.a=2) AND (t1.b=13) AND (t1.c=2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT MAX(t1.a),t1.a,t1.b,t1.c @@ -350,6 +387,7 @@ FROM t1 WHERE (t1.b=13) GROUP BY t1.b HAVING (t1.a=2) AND (t1.c=2); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # extracted AND formula : using equalities @@ -361,11 +399,13 @@ HAVING (t1.a=t1.c) AND (t1.c>1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) FROM t1 WHERE (t1.a=t1.c) AND (t1.a>1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -376,12 +416,14 @@ HAVING (t1.a=t1.c) AND (t1.c=2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a=t1.c) AND (t1.a=2) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -392,6 +434,7 @@ HAVING ((t1.a=t1.c) AND (t1.a>1)) OR ((t1.a<3) AND (t1.c>3)); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -399,6 +442,7 @@ FROM t1 WHERE ((t1.a=t1.c) AND (t1.a>1)) OR (t1.a<3) GROUP BY t1.a HAVING ((t1.a=t1.c) AND (t1.a>1)) OR ((t1.a<3) AND (t1.c>3)); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjuctive subformula : pushdown using WHERE multiple equalities @@ -411,12 +455,14 @@ HAVING (t1.c<3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a=t1.c) AND (t1.c<3) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # extracted AND-formula : pushdown using WHERE multiple equalities @@ -429,12 +475,14 @@ HAVING (t1.a>1) AND (t1.c<3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a=t1.c) AND (t1.a>1) AND (t1.c<3) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -446,6 +494,7 @@ HAVING (((t1.a>1) AND (MAX(t1.c)<3)) OR (t1.c<4)) AND (t1.a<2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -453,6 +502,7 @@ FROM t1 WHERE (t1.a=t1.c) AND (((t1.a>1) OR (t1.c<4)) AND (t1.a<2)) GROUP BY t1.a HAVING ((t1.a>1) AND (MAX(t1.c)<3)) OR (t1.c<4); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # extracted OR-formula : pushdown using WHERE multiple equalities @@ -465,6 +515,7 @@ HAVING ((t1.a>1) AND (MAX(t1.c)<3)) OR (t1.c<4); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -472,6 +523,7 @@ FROM t1 WHERE (t1.a=t1.c) AND ((t1.a>1) OR (t1.c<4)) GROUP BY t1.a HAVING ((t1.a>1) AND (MAX(t1.c)<3)) OR (t1.c<4); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; DROP TABLE t1,t2; @@ -510,12 +562,14 @@ HAVING t1.b = 13 AND MAX(t1.c) > 2; eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 GROUP BY t1.a HAVING t1.b = 13 AND MAX(t1.c) > 2; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # extracted AND formula @@ -527,12 +581,14 @@ HAVING (t1.a = 1 OR t1.b > 10) AND (t1.b < 14); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.a = 1 OR t1.b > 10) AND (t1.b < 14) GROUP BY t1.a,t1.b; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -543,12 +599,14 @@ HAVING (t1.a = 1 OR t1.b > 10) AND (t1.b < 14 OR t1.b > 15); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.a = 1 OR t1.b > 10) AND (t1.b < 14 OR t1.b > 15) GROUP BY t1.a,t1.b; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # extracted AND formula : equality in the inner AND formula @@ -560,12 +618,14 @@ HAVING (t1.a = 1 OR t1.b > 10) AND (t1.b < 14 OR (t1.b > 15 AND t1.a = 2)); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.a = 1 OR t1.b > 10) AND (t1.b < 14 OR (t1.b > 15 AND t1.a = 2)) GROUP BY t1.a,t1.b; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # extracted OR formula @@ -577,12 +637,14 @@ HAVING (t1.a < 2) OR (t1.b = 13 AND t1.a > 2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.a < 2) OR (t1.b = 13 AND t1.a > 2) GROUP BY t1.a,t1.b; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -593,12 +655,14 @@ HAVING (t1.a < 2 AND t1.b = 14) OR (t1.a > 2 AND t1.b = 13); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.a < 2 AND t1.b = 14) OR (t1.a > 2 AND t1.b = 13) GROUP BY t1.a,t1.b; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -609,12 +673,14 @@ HAVING (t1.a < 2 AND t1.b = 14) OR (t1.a > 2 AND (t1.b = 13 OR t1.b = 14)); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.a < 2 AND t1.b = 14) OR (t1.a > 2 AND (t1.b = 13 OR t1.b = 14)) GROUP BY t1.a,t1.b; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -625,6 +691,7 @@ HAVING (t1.a < 2 AND MAX(t1.c) = 2) OR (MAX(t1.c) > 2 AND (t1.a = 1 OR t1.a = 2) eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) @@ -632,6 +699,7 @@ FROM t1 WHERE (t1.a < 2) OR (t1.a = 1 OR t1.a = 2) GROUP BY t1.a HAVING (t1.a < 2 AND MAX(t1.c) = 2) OR (MAX(t1.c) > 2 AND (t1.a = 1 OR t1.a = 2)); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -642,6 +710,7 @@ HAVING (t1.a = 2 AND MAX(t1.c) = 2) OR (MAX(t1.c) > 2 AND (t1.a = 1 OR t1.a = 2) eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) @@ -649,6 +718,7 @@ FROM t1 WHERE (t1.a = 2) OR (t1.a = 1 OR t1.a = 2) GROUP BY t1.a HAVING (t1.a = 2 AND MAX(t1.c) = 2) OR (MAX(t1.c) > 2 AND (t1.a = 1 OR t1.a = 2)); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : equality pushdown @@ -660,6 +730,7 @@ HAVING (t1.a = 1) AND (MAX(t1.c) = 3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) @@ -667,6 +738,7 @@ FROM t1 WHERE (t1.a = 1) GROUP BY t1.a HAVING (MAX(t1.c) = 3); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : equalities pushdown @@ -678,6 +750,7 @@ HAVING (t1.a = 1) AND (t1.c = 3) AND MAX(t1.b = 14); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) @@ -685,6 +758,7 @@ FROM t1 WHERE (t1.a = 1) AND (t1.c = 3) GROUP BY t1.a,t1.c HAVING (MAX(t1.b) = 14); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # conjunctive subformula : multiple equality consists of @@ -697,6 +771,7 @@ HAVING (t1.a = 1) AND (t1.c = 1) AND MAX(t1.b = 14); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) @@ -704,6 +779,7 @@ FROM t1 WHERE (t1.a = 1) AND (t1.c = 1) GROUP BY t1.a,t1.c HAVING (MAX(t1.b) = 14); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # @@ -720,12 +796,14 @@ HAVING (t1.a < 3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.b > 2) AND (t1.a < 3) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # equality : inequality in WHERE @@ -738,12 +816,14 @@ HAVING (t1.a = 3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.b > 2) AND (t1.a = 3) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # inequality : equality in WHERE @@ -756,12 +836,14 @@ HAVING (t1.a < 3); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.b = 14) AND (t1.a < 3) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # equality : equality in WHERE @@ -774,12 +856,14 @@ HAVING (t1.a = 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,t1.b,MAX(t1.c) FROM t1 WHERE (t1.b = 14) AND (t1.a = 1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # equality : equality in WHERE, impossible WHERE @@ -792,12 +876,14 @@ HAVING (t1.a = 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.c) FROM t1 WHERE (t1.a = 3) AND (t1.a = 1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # equality : equality in WHERE (equal through constant) @@ -810,12 +896,14 @@ HAVING (t1.a = 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.c = 1) AND (t1.a = 1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # inequality : AND formula in WHERE @@ -828,12 +916,14 @@ HAVING (t1.a > 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.c > 0) AND (t1.c < 3) AND (t1.a > 1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # equality : AND formula in WHERE @@ -846,12 +936,14 @@ HAVING (t1.a = 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.c > 0) AND (t1.c < 3) AND (t1.a = 1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # equality : AND formula in WHERE, impossible WHERE @@ -864,12 +956,14 @@ HAVING (t1.a = 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a > 0) AND (t1.c < 3) AND (t1.a = 1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -881,12 +975,14 @@ HAVING (t1.a = 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) FROM t1 WHERE (t1.a = 0) AND (t1.a = 3) AND (t1.a = 1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -898,12 +994,14 @@ HAVING (t3.a = 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t3.a,t3.b,MAX(t3.c),t3.d FROM t3 WHERE (t3.b = 2) AND (t3.d = 1) AND (t3.a = 1) GROUP BY t3.a,t3.b,t3.d; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # inequality : OR formula in WHERE @@ -916,12 +1014,14 @@ HAVING (t1.a < 2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE ((t1.a > 1) OR (t1.c < 3)) AND (t1.a < 2) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -933,12 +1033,14 @@ HAVING (t1.a = 2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b) FROM t1 WHERE ((t1.a = 1) OR (t1.a = 3)) AND (t1.a = 2) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # AND formula : inequality in WHERE @@ -951,12 +1053,14 @@ HAVING (t1.a < 4) AND (t1.a > 0); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a > 1) AND (t1.a < 4) AND (t1.a > 0) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # AND formula : equality in WHERE @@ -969,12 +1073,14 @@ HAVING (t1.a < 4) AND (t1.a > 0); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a = 1) AND (t1.a < 4) AND (t1.a > 0) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # OR formula : inequality in WHERE @@ -987,12 +1093,14 @@ HAVING (t1.a < 4) OR (t1.a > 0); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a > 1) AND ((t1.a < 4) OR (t1.a > 0)) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # OR formula : equality in WHERE @@ -1005,12 +1113,14 @@ HAVING (t1.a < 4) OR (t1.a > 0); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a = 1) AND ((t1.a < 4) OR (t1.a > 0)) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # AND formula : AND formula in WHERE @@ -1023,6 +1133,7 @@ HAVING (t1.a < 4) AND (t1.c > 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1031,6 +1142,7 @@ WHERE ((t1.a > 1) AND (t1.c < 3)) AND (t1.a < 4) GROUP BY t1.a HAVING (t1.c > 1); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -1042,6 +1154,7 @@ HAVING (t1.a < 4) AND (t1.c > 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1049,6 +1162,7 @@ FROM t1 WHERE ((t1.a = 1) AND (t1.c < 3)) AND ((t1.a < 4) AND (t1.c > 1)) GROUP BY t1.a,t1.c; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -1060,6 +1174,7 @@ HAVING (t1.a < 4) AND (t1.c > 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1067,6 +1182,7 @@ FROM t1 WHERE ((t1.a = 1) AND (t1.c = 3)) AND ((t1.a < 4) AND (t1.c > 1)) GROUP BY t1.a,t1.c; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -1078,6 +1194,7 @@ HAVING (t3.b = 2) AND (t3.d > 0); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t3.a,t3.b,MAX(t3.c),t3.d @@ -1086,6 +1203,7 @@ WHERE (t3.a = 1) AND (t3.d = 1) AND (t3.b = 2) GROUP BY t3.a,t3.b HAVING (t3.d > 0); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -1097,6 +1215,7 @@ HAVING (t3.b = 2) AND (t3.d > 0); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t3.a,t3.b,MAX(t3.c),t3.d @@ -1104,6 +1223,7 @@ FROM t3 WHERE (t3.a = 1) AND (t3.d = 1) AND (t3.b = 2) AND (t3.d > 0) GROUP BY t3.a,t3.b,t3.d; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # AND formula : OR formula in WHERE @@ -1116,6 +1236,7 @@ HAVING (t1.a < 4) AND (t1.c > 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1124,6 +1245,7 @@ WHERE ((t1.a > 1) OR (t1.c < 3)) AND (t1.a < 4) GROUP BY t1.a HAVING (t1.c > 1); +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -1135,6 +1257,7 @@ HAVING (t1.a < 4) AND (t1.c > 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1142,6 +1265,7 @@ FROM t1 WHERE ((t1.a > 1) OR (t1.c < 3)) AND (t1.a < 4) AND (t1.c > 1) GROUP BY t1.a,t1.c; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -1153,6 +1277,7 @@ HAVING (t1.a = 4) OR (t1.c > 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1160,6 +1285,7 @@ FROM t1 WHERE ((t1.a = 1) OR (t1.a = 3)) AND ((t1.a = 4) OR (t1.c > 1)) GROUP BY t1.a,t1.c; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # equality : pushdown through equality in WHERE @@ -1172,12 +1298,14 @@ HAVING (t1.c = 1); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c FROM t1 WHERE (t1.a = 1) AND (t1.a = t1.c) AND (t1.c = 1) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # OR formula : pushdown through equality @@ -1190,6 +1318,7 @@ HAVING (t1.c = 1) OR (t1.c = 2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1197,6 +1326,7 @@ FROM t1 WHERE (t1.a = 1) AND (t1.a = t1.c) AND ((t1.c = 1) OR (t1.c = 2)) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # OR formula : pushdown through equality, impossible WHERE @@ -1209,6 +1339,7 @@ HAVING (t1.c = 3) OR (t1.c = 2); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1216,6 +1347,7 @@ FROM t1 WHERE (t1.a = 1) AND (t1.a = t1.c) AND ((t1.c = 3) OR (t1.c = 2)) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # AND formula : pushdown through equality, impossible WHERE @@ -1228,6 +1360,7 @@ HAVING (t1.c = 3) AND (t1.a > 2) AND (t1.a = t1.c); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1235,6 +1368,7 @@ FROM t1 WHERE (t1.a = 1) AND (t1.c = 3) AND (t1.a > 2) AND (t1.a = t1.c) GROUP BY t1.a,t1.c; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; let $query= @@ -1246,6 +1380,7 @@ HAVING (t1.c = 3) AND (t1.a > 2) AND (t1.a = t1.c); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t1.a,MAX(t1.b),t1.c @@ -1253,6 +1388,7 @@ FROM t1 WHERE (t1.a = 1) AND (t1.c = 3) AND (t1.a > 2) AND (t1.a = t1.c) GROUP BY t1.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # AND formula with OR subformula : AND condition in WHERE @@ -1265,6 +1401,7 @@ HAVING (t3.a = t3.d) AND ((t3.d = 1) OR (t3.d > 1)); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t3.a,MAX(t3.c),t3.d @@ -1272,6 +1409,7 @@ FROM t3 WHERE (t3.a > 1) AND ((t3.c = 3) OR (t3.c < 2)) AND (t3.a = t3.d) AND ((t3.d = 1) OR (t3.d > 1)) GROUP BY t3.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # AND formula with OR subformula : AND condition in WHERE @@ -1284,6 +1422,7 @@ HAVING (t3.a = t3.d) AND (((t3.d = t3.c) AND (t3.c < 15)) OR (t3.d > 1)); eval $no_pushdown $query; eval $query; eval explain $query; +--source include/explain-no-costs.inc eval explain format=json $query; let $query= SELECT t3.a,t3.b,MAX(t3.c),t3.d @@ -1291,6 +1430,7 @@ FROM t3 WHERE (t3.a > 1) AND ((t3.c = 3) OR (t3.c < 2)) AND (t3.a = t3.d) AND (((t3.d = t3.c) AND (t3.c < 15)) OR (t3.d > 1)) GROUP BY t3.a; +--source include/explain-no-costs.inc eval $no_pushdown explain format=json $query; --echo # prepare statement @@ -1359,6 +1499,7 @@ select d1 from t1 eval $q1; eval explain extended $q1; +--source include/explain-no-costs.inc eval explain format=json $q1; delete from t1; @@ -1371,6 +1512,7 @@ select d1 from t1 eval $q2; eval explain extended $q2; +--source include/explain-no-costs.inc eval explain format=json $q2; drop table t1; @@ -1420,6 +1562,7 @@ INSERT INTO t2 VALUES (2),(3); let $q= SELECT a FROM t1 GROUP BY a HAVING a = 8 OR a = ( SELECT MIN(c) FROM t2 ); +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q; eval $q; @@ -1427,6 +1570,7 @@ let $q= SELECT a FROM t1 GROUP BY a,b HAVING ( a = 8 OR a = ( SELECT MIN(c) FROM t2 ) ) and b < 20; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q; eval $q; @@ -1434,12 +1578,14 @@ let $q= SELECT a FROM t1 GROUP BY a HAVING ( a = 8 OR a = ( SELECT MIN(c) FROM t2 ) ) and SUM(b) > 20; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q; eval $q; let $q= SELECT a FROM t1 GROUP BY a HAVING a = ( SELECT MIN(c) FROM t2 ); +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $q; eval $q; diff --git a/mysql-test/main/ignored_index.result b/mysql-test/main/ignored_index.result index 03748d48098..176ca61decd 100644 --- a/mysql-test/main/ignored_index.result +++ b/mysql-test/main/ignored_index.result @@ -255,17 +255,15 @@ DROP TABLE t1; # IGNORED fulltext indexes. # CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b)); -INSERT INTO t1 VALUES('Some data', 'for full-text search'); -ANALYZE TABLE t1; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze Warning Engine-independent statistics are not collected for column 'b' -test.t1 analyze status OK -EXPLAIN SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ("collections"); +INSERT INTO t1 VALUES('Some data', 'for full-text search'),("hello","hello world"),("mars","here I come"); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ("search"); +a b +Some data for full-text search +EXPLAIN SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ("search"); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 fulltext a a 0 1 Using where ALTER TABLE t1 ALTER INDEX a IGNORED; -EXPLAIN SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ("collections"); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ("search"); ERROR HY000: Can't find FULLTEXT index matching the column list DROP TABLE t1; # diff --git a/mysql-test/main/ignored_index.test b/mysql-test/main/ignored_index.test index a3d46fe6046..b2fadcd5862 100644 --- a/mysql-test/main/ignored_index.test +++ b/mysql-test/main/ignored_index.test @@ -222,13 +222,11 @@ DROP TABLE t1; --echo # IGNORED fulltext indexes. --echo # CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b)); -INSERT INTO t1 VALUES('Some data', 'for full-text search'); -ANALYZE TABLE t1; - -let $query= -EXPLAIN SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ("collections"); +INSERT INTO t1 VALUES('Some data', 'for full-text search'),("hello","hello world"),("mars","here I come"); +let $query=SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ("search"); --eval $query +--eval EXPLAIN $query ALTER TABLE t1 ALTER INDEX a IGNORED; --error ER_FT_MATCHING_KEY_NOT_FOUND diff --git a/mysql-test/main/in_subq_cond_pushdown.result b/mysql-test/main/in_subq_cond_pushdown.result index f114fc6824e..d0431852614 100644 --- a/mysql-test/main/in_subq_cond_pushdown.result +++ b/mysql-test/main/in_subq_cond_pushdown.result @@ -51,12 +51,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c < 25 and t1.a is not null and t1.c is not null" } @@ -70,12 +73,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.g)` < 25", "temporary_table": { "nested_loop": [ @@ -83,7 +89,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -150,12 +158,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c > 55 and t1.b < 4 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -169,12 +180,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.g)` > 55 and t2.f < 4", "temporary_table": { "nested_loop": [ @@ -182,7 +196,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -251,12 +267,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.c > 60 or t1.c < 25) and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -270,12 +289,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.g)` > 60 or `MAX(t2.g)` < 25", "temporary_table": { "nested_loop": [ @@ -283,7 +305,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -350,12 +374,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.c > 60 or t1.c < 25) and t1.b > 2 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -369,12 +396,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "(`MAX(t2.g)` > 60 or `MAX(t2.g)` < 25) and t2.f > 2", "temporary_table": { "nested_loop": [ @@ -382,7 +412,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -451,12 +483,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a < 2 or t1.d > 3) and t1.b > 1 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -470,12 +505,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "t2.f > 1", "temporary_table": { "nested_loop": [ @@ -483,7 +521,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -550,12 +590,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c > 20 and t1.a is not null and t1.c is not null" } @@ -569,12 +612,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["v1_x", "MAX(v1_y)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(v1_y)` > 20", "temporary_table": { "nested_loop": [ @@ -582,7 +628,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.x > 1 and t3.x <= 3" } @@ -650,12 +698,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.y > 20 and t3.x <= 3 and t3.y is not null" } @@ -665,7 +716,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 8, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -683,12 +736,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t3.y"], + "loops": 128, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.g)` > 20", "temporary_table": { "nested_loop": [ @@ -696,7 +752,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -765,12 +823,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 2 and t1.a is not null and t1.c is not null" } @@ -784,19 +845,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e < 2" } @@ -865,12 +931,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 2 and t1.a < 5 and t1.a is not null and t1.c is not null" } @@ -884,19 +953,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e > 2 and t2.e < 5" } @@ -967,12 +1041,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a < 2 or t1.a >= 4) and t1.a is not null and t1.c is not null" } @@ -986,19 +1063,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and (t2.e < 2 or t2.e >= 4)" } @@ -1065,12 +1147,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a < 2 or t1.a = 5) and t1.b > 3 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -1084,19 +1169,24 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and (t2.e < 2 or t2.e = 5) and t2.f > 3" } @@ -1163,12 +1253,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a < 2 or t1.a = 5) and t1.b > 3 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -1182,19 +1275,24 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and (t2.e < 2 or t2.e = 5) and t2.f > 3" } @@ -1261,12 +1359,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.b < 3 or t1.d > 2) and t1.a < 2 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -1280,19 +1381,24 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e < 2" } @@ -1359,12 +1465,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a = 1 and t1.d = 1 and t1.c is not null" } @@ -1378,18 +1487,23 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["const", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e = 1" } @@ -1455,12 +1569,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.d = t1.a and t1.a > 1 and t1.a is not null and t1.c is not null" } @@ -1474,19 +1591,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e > 1" } @@ -1551,12 +1673,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 3 and t1.a is not null and t1.c is not null" } @@ -1570,19 +1695,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["v1_x", "MAX(v1_y)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.x > 1 and t3.x <= 3 and t3.x < 3" } @@ -1652,12 +1782,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.x < 2 and t3.y > 30 and t3.x <= 3 and t3.x is not null" } @@ -1667,7 +1800,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 8, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -1685,19 +1820,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t3.x", "test.t1.c"], + "loops": 128, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e <= 3" } @@ -1765,12 +1905,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.b < 3 or t1.b = 4) and t1.a < 3 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -1784,12 +1927,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "t2.f < 3 or t2.f = 4", "temporary_table": { "nested_loop": [ @@ -1797,7 +1943,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e < 3" } @@ -1864,12 +2012,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a + t1.c > 41 and t1.a is not null and t1.c is not null" } @@ -1883,12 +2034,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "t2.e + `MAX(t2.g)` > 41", "temporary_table": { "nested_loop": [ @@ -1896,7 +2050,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -1965,12 +2121,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c - t1.a < 35 and t1.a is not null and t1.c is not null" } @@ -1984,12 +2143,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.g)` - t2.e < 35", "temporary_table": { "nested_loop": [ @@ -1997,7 +2159,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -2064,12 +2228,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c * t1.a > 100 and t1.a is not null and t1.c is not null" } @@ -2083,12 +2250,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.g)` * t2.e > 100", "temporary_table": { "nested_loop": [ @@ -2096,7 +2266,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -2167,12 +2339,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c / t1.a > 30 and t1.a is not null and t1.c is not null" } @@ -2186,12 +2361,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.g)` / t2.e > 30", "temporary_table": { "nested_loop": [ @@ -2199,7 +2377,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -2266,12 +2446,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c between 50 and 100 and t1.a is not null and t1.c is not null" } @@ -2285,12 +2468,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "`MAX(t2.g)` between 50 and 100", "temporary_table": { "nested_loop": [ @@ -2298,7 +2484,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -2365,12 +2553,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a + t1.b > 5 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -2384,19 +2575,24 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e + t2.f > 5" } @@ -2463,12 +2659,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a - t1.b > 0 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -2482,19 +2681,24 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e - t2.f > 0" } @@ -2561,12 +2765,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a * t1.b > 6 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -2580,19 +2787,24 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e * t2.f > 6" } @@ -2661,12 +2873,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b / t1.a > 2 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -2680,19 +2895,24 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.f / t2.e > 2" } @@ -2765,12 +2985,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a between 1 and 3 and t1.a is not null and t1.c is not null" } @@ -2784,19 +3007,24 @@ EXPLAIN "key_length": "8", "used_key_parts": ["e", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e between 1 and 3" } @@ -2867,12 +3095,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c > 3 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -2886,12 +3117,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "MAX(v2.f)", "max_g"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "v2.max_g > 3", "temporary_table": { "nested_loop": [ @@ -2899,12 +3133,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.e < 5", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_g > 25", "filesort": { "sort_key": "t2.e", @@ -2914,7 +3151,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5" } @@ -2991,12 +3230,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -3010,24 +3252,30 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "MAX(v2.f)", "max_g"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.e < 5 and v2.e > 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_g > 25", "filesort": { "sort_key": "t2.e", @@ -3037,7 +3285,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e > 1" } @@ -3115,12 +3365,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.c < 100 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -3134,12 +3387,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "MAX(v2.f)", "max_g"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "v2.max_g < 100", "temporary_table": { "nested_loop": [ @@ -3147,12 +3403,15 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v2.e < 5 and v2.e > 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_g > 25", "filesort": { "sort_key": "t2.e", @@ -3162,7 +3421,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.e > 1" } @@ -3263,12 +3524,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -3282,24 +3546,30 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "MAX(d_tab.f)", "max_g"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "d_tab.e < 5 and d_tab.e > 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_g > 25 and t2.e < 5 and t2.e > 1", "filesort": { "sort_key": "t2.f", @@ -3309,7 +3579,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3428,12 +3700,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -3447,24 +3722,30 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "MAX(d_tab.f)", "max_g"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "d_tab.e < 5 and d_tab.e > 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_g > 25 and t2.e < 5 and t2.e > 1", "filesort": { "sort_key": "t2.f", @@ -3474,7 +3755,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3594,12 +3877,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -3613,24 +3899,30 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "MAX(d_tab.f)", "max_g"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "d_tab.e < 5 and d_tab.e > 1", "materialized": { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "max_g > 25 and t2.e < 5 and t2.e > 1", "filesort": { "sort_key": "t2.f", @@ -3640,7 +3932,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3718,7 +4012,7 @@ GROUP BY t1.a WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where -1 PRIMARY ref key0 key0 5 test.t3.x 2 Using where +1 PRIMARY ref key0 key0 5 test.t3.x 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 16 Using where; Using temporary; Using filesort 2 DERIVED eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1 3 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary @@ -3742,12 +4036,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.x < 5 and t3.x is not null" } @@ -3761,12 +4058,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t3.x"], - "rows": 2, + "loops": 8, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "d_tab.max_c < 70", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 70", "filesort": { "sort_key": "t1.a", @@ -3776,7 +4076,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a < 5 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -3790,12 +4092,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "t2.f < 5", "temporary_table": { "nested_loop": [ @@ -3803,7 +4108,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e > 1 and t2.e < 5" } @@ -3903,7 +4210,7 @@ GROUP BY t1.a WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where -1 PRIMARY ref key0 key0 5 test.t3.x 2 Using where +1 PRIMARY ref key0 key0 5 test.t3.x 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 16 Using where; Using temporary; Using filesort 2 DERIVED eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1 3 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary @@ -3927,12 +4234,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t3.x < 5 and t3.x is not null" } @@ -3946,12 +4256,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t3.x"], - "rows": 2, + "loops": 8, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "d_tab.max_c < 70", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "having_condition": "max_c < 70", "filesort": { "sort_key": "t1.a", @@ -3961,7 +4274,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a > 1 and t1.a < 5 and t1.a is not null and t1.b is not null and t1.c is not null" } @@ -3975,12 +4290,15 @@ EXPLAIN "key_length": "12", "used_key_parts": ["e", "f", "MAX(t2.g)"], "ref": ["test.t1.a", "test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "having_condition": "t2.f < 5", "temporary_table": { "nested_loop": [ @@ -3988,7 +4306,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e > 1 and t2.e < 5" } @@ -4065,12 +4385,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 1 and t1.b is not null and t1.c is not null" } @@ -4084,12 +4407,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["f", "MAX(t2.g) OVER (PARTITION BY t2.f)"], "ref": ["test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -4104,7 +4430,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.f > 1" } @@ -4169,12 +4497,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 16, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b > 1 and t1.b is not null and t1.c is not null" } @@ -4191,13 +4522,16 @@ EXPLAIN "CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)" ], "ref": ["test.t1.b", "test.t1.c"], + "loops": 16, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.c = ``.`CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)`", "materialized": { "unique": 1, "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -4212,7 +4546,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.e < 5 and t2.f > 1" } diff --git a/mysql-test/main/in_subq_cond_pushdown.test b/mysql-test/main/in_subq_cond_pushdown.test index 7763201cda1..8a12a2c5977 100644 --- a/mysql-test/main/in_subq_cond_pushdown.test +++ b/mysql-test/main/in_subq_cond_pushdown.test @@ -42,6 +42,7 @@ WHERE t1.c<25 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # extracted AND formula : pushing into HAVING @@ -60,6 +61,7 @@ WHERE t1.c>55 AND t1.b<4 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # extracted OR formula : pushing into HAVING @@ -78,6 +80,7 @@ WHERE (t1.c>60 OR t1.c<25) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # extracted AND-OR formula : pushing into HAVING @@ -96,6 +99,7 @@ WHERE ((t1.c>60 OR t1.c<25) AND t1.b>2) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into HAVING @@ -114,6 +118,7 @@ WHERE ((t1.a<2 OR t1.d>3) AND t1.b>1) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # using view IN subquery defINition : pushing into HAVING @@ -132,6 +137,7 @@ WHERE t1.c>20 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # using equality : pushing into WHERE @@ -150,6 +156,7 @@ WHERE t1.c>20 AND t1.c=v1_y AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE @@ -168,6 +175,7 @@ WHERE t1.a<2 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # extracted AND formula : pushing into WHERE @@ -186,6 +194,7 @@ WHERE t1.a>2 AND t1.a<5 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # extracted OR formula : pushing into WHERE @@ -204,6 +213,7 @@ WHERE (t1.a<2 OR t1.a>=4) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # extracted AND-OR formula : pushing into WHERE @@ -222,6 +232,7 @@ WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # extracted AND-OR formula : pushing into WHERE @@ -240,6 +251,7 @@ WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE @@ -258,6 +270,7 @@ WHERE ((t1.b<3 OR t1.d>2) AND t1.a<2) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # using equalities : pushing into WHERE @@ -276,6 +289,7 @@ WHERE t1.d=1 AND t1.a=t1.d AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # using equality : pushing into WHERE @@ -294,6 +308,7 @@ WHERE t1.d>1 AND t1.a=t1.d AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # using view IN subquery definition : pushing into WHERE @@ -312,6 +327,7 @@ WHERE t1.a<3 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # using equality : pushing into WHERE @@ -330,6 +346,7 @@ WHERE t1.a=v1_x AND v1_x<2 AND v1_y>30 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE @@ -349,6 +366,7 @@ WHERE ((t1.b<3 OR t1.b=4) AND t1.a<3) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using addition : pushing into HAVING @@ -367,6 +385,7 @@ WHERE (t1.a+t1.c>41) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using substitution : pushing into HAVING @@ -385,6 +404,7 @@ WHERE (t1.c-t1.a<35) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using multiplication : pushing into HAVING @@ -403,6 +423,7 @@ WHERE (t1.c*t1.a>100) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using division : pushing into HAVING @@ -421,6 +442,7 @@ WHERE (t1.c/t1.a>30) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using BETWEEN : pushing into HAVING @@ -439,6 +461,7 @@ WHERE (t1.c BETWEEN 50 AND 100) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using addition : pushing into WHERE @@ -457,6 +480,7 @@ WHERE (t1.a+t1.b > 5) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using substitution : pushing into WHERE @@ -475,6 +499,7 @@ WHERE (t1.a-t1.b > 0) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using multiplication : pushing into WHERE @@ -493,6 +518,7 @@ WHERE (t1.a*t1.b > 6) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using division : pushing into WHERE @@ -511,6 +537,7 @@ WHERE (t1.b/t1.a > 2) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula using BETWEEN : pushing into WHERE @@ -529,6 +556,7 @@ WHERE (t1.a BETWEEN 1 AND 3) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into HAVING of the IN subquery @@ -548,6 +576,7 @@ WHERE t1.c>3 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE of the IN subquery @@ -568,6 +597,7 @@ WHERE t1.a>1 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE and HAVING @@ -589,6 +619,7 @@ WHERE t1.a>1 AND t1.c<100 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE of the IN subquery @@ -615,6 +646,7 @@ WHERE t1.a>1 AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into HAVING of the derived table @@ -640,6 +672,7 @@ WHERE d_tab.a=t3.x AND d_tab.b>2; EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE of the derived table @@ -665,6 +698,7 @@ WHERE d_tab.a=t3.x AND d_tab.a<5; EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE and HAVING @@ -692,6 +726,7 @@ WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70; EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE of the derived table @@ -717,6 +752,7 @@ WHERE d_tab.a=t3.x AND d_tab.a<5; EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE @@ -735,6 +771,7 @@ WHERE (t1.b>1) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; --echo # conjunctive subformula : pushing into WHERE @@ -753,6 +790,7 @@ WHERE (t1.b>1) AND EVAL $no_pushdown $query; EVAL $query; EVAL EXPLAIN $query; +--source include/explain-no-costs.inc EVAL EXPLAIN FORMAT=JSON $query; DROP TABLE t1,t2,t3; diff --git a/mysql-test/main/index_intersect.result b/mysql-test/main/index_intersect.result index 3ec98216479..c6332591ff5 100644 --- a/mysql-test/main/index_intersect.result +++ b/mysql-test/main/index_intersect.result @@ -80,7 +80,7 @@ EXPLAIN SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 7000000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Population 4 NULL # Using index condition; Using where SELECT * FROM City USE INDEX () WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population @@ -335,8 +335,8 @@ ID Name Country Population SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 7000000; ID Name Country Population -1024 Mumbai (Bombay) IND 10500000 3580 Moscow RUS 8389200 +1024 Mumbai (Bombay) IND 10500000 SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N'; COUNT(*) 301 @@ -355,9 +355,6 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; COUNT(*) 551 -SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; -COUNT(*) -339 SELECT COUNT(*) FROM City WHERE Country LIKE 'J%'; COUNT(*) 256 @@ -370,12 +367,12 @@ EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'K' AND Population > 1000000 AND Country LIKE 'J%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name Population,Country,Name 4,3,35 NULL # Using sort_intersect(Population,Country,Name); Using where +1 SIMPLE City index_merge Population,Country,Name Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Name,Country Name,Country,Population # NULL # Using sort_intersect(Name,Country,Population); Using where +1 SIMPLE City index_merge Population,Name,Country Name,Country # NULL # Using sort_intersect(Name,Country); Using where SELECT * FROM City USE INDEX () WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; ID Name Country Population @@ -466,17 +463,17 @@ EXPLAIN SELECT * FROM City WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country Population,PRIMARY,Country 4,4,3 NULL # Using sort_intersect(Population,PRIMARY,Country); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country Population,PRIMARY 4,4 NULL # Using sort_intersect(Population,PRIMARY); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country Population,PRIMARY,Country 4,4,3 NULL # Using sort_intersect(Population,PRIMARY,Country); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country Population,PRIMARY 4,4 NULL # Using sort_intersect(Population,PRIMARY); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country Country,PRIMARY 3,4 NULL # Using sort_intersect(Country,PRIMARY); Using where +1 SIMPLE City range PRIMARY,Population,Country Country 3 NULL # Using index condition; Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 @@ -488,7 +485,7 @@ SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where +1 SIMPLE City index_merge PRIMARY,Population,Country Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where SELECT * FROM City USE INDEX () WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population @@ -720,13 +717,13 @@ EXPLAIN SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where +1 SIMPLE City index_merge PRIMARY,Population,Country Population,PRIMARY 4,4 NULL # Using sort_intersect(Population,PRIMARY); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where +1 SIMPLE City index_merge PRIMARY,Population,Country Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population @@ -966,7 +963,7 @@ EXPLAIN SELECT * FROM t1 WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,f4 f4 35 NULL # Using index condition; Using where +1 SIMPLE t1 index_merge PRIMARY,f4 f4,PRIMARY 35,4 NULL # Using sort_intersect(f4,PRIMARY); Using where SELECT * FROM t1 WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; f1 f4 f5 diff --git a/mysql-test/main/index_intersect.test b/mysql-test/main/index_intersect.test index 26937fd5eef..d6208f67a92 100644 --- a/mysql-test/main/index_intersect.test +++ b/mysql-test/main/index_intersect.test @@ -120,7 +120,6 @@ SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'K'; SELECT COUNT(*) FROM City WHERE Population > 1000000; SELECT COUNT(*) FROM City WHERE Population > 500000; SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; -SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; SELECT COUNT(*) FROM City WHERE Country LIKE 'J%'; diff --git a/mysql-test/main/index_intersect_innodb.result b/mysql-test/main/index_intersect_innodb.result index 44407dbcd30..2aba9dc6fcf 100644 --- a/mysql-test/main/index_intersect_innodb.result +++ b/mysql-test/main/index_intersect_innodb.result @@ -81,12 +81,12 @@ EXPLAIN SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 300000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name Name 35 NULL # Using index condition; Using where +1 SIMPLE City index_merge Population,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where EXPLAIN SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 7000000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Population 4 NULL # Using index condition; Using where SELECT * FROM City USE INDEX () WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population @@ -341,8 +341,8 @@ ID Name Country Population SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 7000000; ID Name Country Population -1024 Mumbai (Bombay) IND 10500000 3580 Moscow RUS 8389200 +1024 Mumbai (Bombay) IND 10500000 SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N'; COUNT(*) 301 @@ -361,9 +361,6 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; COUNT(*) 551 -SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; -COUNT(*) -339 SELECT COUNT(*) FROM City WHERE Country LIKE 'J%'; COUNT(*) 256 @@ -371,17 +368,17 @@ EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name Population,Name,Country 4,35,3 NULL # Using sort_intersect(Population,Name,Country); Using where +1 SIMPLE City index_merge Population,Country,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'K' AND Population > 1000000 AND Country LIKE 'J%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name Population,Country,Name 4,3,35 NULL # Using sort_intersect(Population,Country,Name); Using where +1 SIMPLE City index_merge Population,Country,Name Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name,Country Name # NULL # Using index condition; Using where +1 SIMPLE City index_merge Population,Name,Country Name,Population # NULL # Using sort_intersect(Name,Population); Using where SELECT * FROM City USE INDEX () WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; ID Name Country Population @@ -472,29 +469,29 @@ EXPLAIN SELECT * FROM City WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City range PRIMARY,Population,Country PRIMARY 4 NULL # Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City range PRIMARY,Population,Country PRIMARY 4 NULL # Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City range PRIMARY,Population,Country Country 7 NULL # Using index condition; Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 AND Country BETWEEN 'S' AND 'Z'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population 4,4 NULL # Using sort_intersect(PRIMARY,Population); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population 4,4 NULL # Using sort_intersect(PRIMARY,Population); Using where SELECT * FROM City USE INDEX () WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population @@ -711,7 +708,7 @@ EXPLAIN SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 1500000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Population 4 NULL # Using index condition; Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'K' AND Population > 1000000 AND Country LIKE 'J%'; @@ -721,12 +718,12 @@ EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Name 35 NULL # Using index condition; Using where +1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City range PRIMARY,Population,Country PRIMARY 4 NULL # Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 diff --git a/mysql-test/main/index_merge_innodb.result b/mysql-test/main/index_merge_innodb.result index d9be08a0540..6f1daf7552c 100644 --- a/mysql-test/main/index_merge_innodb.result +++ b/mysql-test/main/index_merge_innodb.result @@ -582,7 +582,7 @@ set @tmp_index_merge_ror_cpk=@@optimizer_switch; set optimizer_switch='extended_keys=off'; explain select * from t1 where pk1 < 7500 and key1 = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge PRIMARY,key1 key1,PRIMARY 4,4 NULL ROWS Using intersect(key1,PRIMARY); Using where +1 SIMPLE t1 ref PRIMARY,key1 key1 4 const ROWS Using index condition set optimizer_switch=@tmp_index_merge_ror_cpk; explain select * from t1 where pktail1ok=1 and key1=10; id select_type table type possible_keys key key_len ref rows Extra @@ -654,7 +654,7 @@ f1 EXPLAIN SELECT t1.f1 FROM t1 WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 2 SUBQUERY t2 index_merge f2,f3 f3,f2 2,5 NULL 1 Using intersect(f3,f2); Using where; Using index DROP TABLE t1,t2; # @@ -827,13 +827,13 @@ INDEX (b) INSERT INTO t1 SELECT seq, seq, seq from seq_1_to_100; EXPLAIN SELECT * FROM t1 WHERE a='1' OR b < 5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge PRIMARY,b b,PRIMARY 5,3074 NULL 5 Using sort_union(b,PRIMARY); Using where +1 SIMPLE t1 ALL PRIMARY,b NULL NULL NULL 100 Using where SELECT * FROM t1 WHERE a='1' OR b < 5; a b c +1 1 1 2 2 2 3 3 3 4 4 4 -1 1 1 DROP TABLE t1; SET sort_buffer_size= @save_sort_buffer_size; disconnect disable_purge; diff --git a/mysql-test/main/index_merge_myisam.result b/mysql-test/main/index_merge_myisam.result index 1ecc1ded83a..2c84086d17d 100644 --- a/mysql-test/main/index_merge_myisam.result +++ b/mysql-test/main/index_merge_myisam.result @@ -232,7 +232,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index i1_3,i2_3 i321 12 NULL 1024 Using where; Using index explain select key7 from t2 where key1 <100 or key2 < 100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 186 Using sort_union(i1_3,i2_3); Using where +1 SIMPLE t2 ALL i1_3,i2_3 NULL NULL NULL 1024 Using where create table t4 ( key1a int not null, key1b int not null, @@ -405,8 +405,8 @@ from t0 as A straight_join t0 as B where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE A index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where -1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where; Using join buffer (flat, BNL join) +1 SIMPLE A ALL i1,i2,i3,i4,i5,i6,i7?,i8 NULL NULL NULL # Using where +1 SIMPLE B ALL i1,i2,i3,i4,i5,i6,i7?,i8 NULL NULL NULL # Using where; Using join buffer (flat, BNL join) select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) from t0 as A straight_join t0 as B where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) @@ -554,7 +554,7 @@ DROP TABLE t1; create table t1 (a int); insert into t1 values (1),(2); create table t2(a int, b int); -insert into t2 values (1,1), (2, 1000); +insert into t2 values (1,1), (2, 1000),(5000,5000); create table t3 (a int, b int, filler char(100), key(a), key(b)); insert into t3 select 1000, 1000,'filler' from seq_1_to_1000; insert into t3 values (1,1,'data'); @@ -566,7 +566,7 @@ where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 2 MATERIALIZED t3 ALL a,b NULL NULL NULL 1002 Range checked for each record (index map: 0x3) select * from t1 where exists (select 1 from t2, t3 @@ -683,7 +683,7 @@ key1 key2 key3 key4 filler1 -1 -1 100 100 key4-key3 explain select key1,key2,key3 from t1 where key1=100 and key2=100 and key3=100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge key1,key2,key3 key1,key2,key3 5,5,5 NULL 2 Using intersect(key1,key2,key3); Using where; Using index +1 SIMPLE t1 index_merge key1,key2,key3 key1,key2 5,5 NULL 77 Using intersect(key1,key2); Using where select key1,key2,key3 from t1 where key1=100 and key2=100 and key3=100; key1 key2 key3 100 100 100 @@ -762,7 +762,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge sta_swt12a,sta_swt1a,sta_swt2a,sta_swt21a,st_a,stb_swt1a_2b,stb_swt1b,st_b st_a,st_b 4,4 NULL 3515 Using intersect(st_a,st_b); Using where; Using index explain select st_a from t1 ignore index (st_a) where st_a=1 and st_b=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref sta_swt12a,sta_swt1a,sta_swt2a,sta_swt21a,stb_swt1a_2b,stb_swt1b,st_b st_b 4 const 15094 Using where +1 SIMPLE t1 ALL sta_swt12a,sta_swt1a,sta_swt2a,sta_swt21a,stb_swt1a_2b,stb_swt1b,st_b NULL NULL NULL 64806 Using where explain select * from t1 where st_a=1 and swt1a=1 and swt2a=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref sta_swt12a,sta_swt1a,sta_swt2a,sta_swt21a,st_a sta_swt21a 12 const,const,const 971 @@ -783,7 +783,7 @@ id select_type table type possible_keys key key_len ref rows Extra explain select * from t1 ignore index (sta_swt21a, sta_swt12a, stb_swt1a_2b, stb_swt1b) where st_a=1 and swt1a=1 and swt2a=1 and st_b=1 and swt1b=1 and swt2b=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge sta_swt1a,sta_swt2a,st_a,st_b sta_swt1a,sta_swt2a,st_b 8,8,4 NULL 223 Using intersect(sta_swt1a,sta_swt2a,st_b); Using where +1 SIMPLE t1 index_merge sta_swt1a,sta_swt2a,st_a,st_b sta_swt1a,sta_swt2a 8,8 NULL 960 Using intersect(sta_swt1a,sta_swt2a); Using where explain select * from t1 where st_a=1 and swt1a=1 and swt2a=1 and st_b=1 and swt1b=1; id select_type table type possible_keys key key_len ref rows Extra @@ -910,7 +910,7 @@ INSERT INTO t1 (key1, key2, filler) SELECT seq/4, seq/8, 'filler-data' FROM seq_30_to_0; explain select pk from t1 where key1 = 1 and key2 = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref key1,key2 key1 5 const 4 Using where +1 SIMPLE t1 index_merge key1,key2 key1,key2 5,4 NULL 1 Using intersect(key1,key2); Using where select pk from t1 where key2 = 1 and key1 = 1; pk 26 @@ -1487,7 +1487,7 @@ EXPLAIN SELECT t1.f1 FROM t1 WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 -2 SUBQUERY t2 ref f2,f3 f3 2 const 2 Using index condition; Using where +2 SUBQUERY t2 index_merge f2,f3 f3,f2 2,5 NULL 1 Using intersect(f3,f2); Using where; Using index DROP TABLE t1,t2; create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -1558,7 +1558,7 @@ This should be intersect: set optimizer_switch=default; explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where +1 SIMPLE t1 ref|filter a,b a|b 5|5 const 49 (1%) Using where; Using rowid filter No intersect when index_merge is disabled: set optimizer_switch='default,index_merge=off,rowid_filter=off'; explain select * from t1 where a=10 and b=10; diff --git a/mysql-test/main/information_schema-big.result b/mysql-test/main/information_schema-big.result index 5c519014800..94c8d274fad 100644 --- a/mysql-test/main/information_schema-big.result +++ b/mysql-test/main/information_schema-big.result @@ -37,6 +37,7 @@ INDEX_STATISTICS TABLE_SCHEMA KEYWORDS WORD KEY_CACHES KEY_CACHE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA +OPTIMIZER_COSTS ENGINE PARAMETERS SPECIFIC_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME @@ -97,6 +98,7 @@ INDEX_STATISTICS TABLE_SCHEMA KEYWORDS WORD KEY_CACHES KEY_CACHE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA +OPTIMIZER_COSTS ENGINE PARAMETERS SPECIFIC_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index e46014e44b9..0c952886d63 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -71,6 +71,7 @@ INDEX_STATISTICS KEYWORDS KEY_CACHES KEY_COLUMN_USAGE +OPTIMIZER_COSTS OPTIMIZER_TRACE PARAMETERS PARTITIONS @@ -1434,7 +1435,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tables ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort explain select * from (select table_name from information_schema.tables) as a; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 +1 PRIMARY ALL NULL NULL NULL NULL 100 2 DERIVED tables ALL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases set optimizer_switch=@tmp_optimizer_switch; drop view v1; diff --git a/mysql-test/main/information_schema_all_engines.result b/mysql-test/main/information_schema_all_engines.result index 23a853e363c..db9bf156b8e 100644 --- a/mysql-test/main/information_schema_all_engines.result +++ b/mysql-test/main/information_schema_all_engines.result @@ -42,6 +42,7 @@ INNODB_TRX KEYWORDS KEY_CACHES KEY_COLUMN_USAGE +OPTIMIZER_COSTS OPTIMIZER_TRACE PARAMETERS PARTITIONS @@ -123,6 +124,7 @@ INNODB_TRX trx_id KEYWORDS WORD KEY_CACHES KEY_CACHE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA +OPTIMIZER_COSTS ENGINE OPTIMIZER_TRACE QUERY PARAMETERS SPECIFIC_SCHEMA PARTITIONS TABLE_SCHEMA @@ -204,6 +206,7 @@ INNODB_TRX trx_id KEYWORDS WORD KEY_CACHES KEY_CACHE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA +OPTIMIZER_COSTS ENGINE OPTIMIZER_TRACE QUERY PARAMETERS SPECIFIC_SCHEMA PARTITIONS TABLE_SCHEMA @@ -289,6 +292,7 @@ INNODB_TABLESPACES_ENCRYPTION information_schema.INNODB_TABLESPACES_ENCRYPTION 1 INNODB_TRX information_schema.INNODB_TRX 1 KEY_CACHES information_schema.KEY_CACHES 1 KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1 +OPTIMIZER_COSTS information_schema.OPTIMIZER_COSTS 1 OPTIMIZER_TRACE information_schema.OPTIMIZER_TRACE 1 PARAMETERS information_schema.PARAMETERS 1 PARTITIONS information_schema.PARTITIONS 1 @@ -359,6 +363,7 @@ Database: information_schema | KEYWORDS | | KEY_CACHES | | KEY_COLUMN_USAGE | +| OPTIMIZER_COSTS | | OPTIMIZER_TRACE | | PARAMETERS | | PARTITIONS | @@ -430,6 +435,7 @@ Database: INFORMATION_SCHEMA | KEYWORDS | | KEY_CACHES | | KEY_COLUMN_USAGE | +| OPTIMIZER_COSTS | | OPTIMIZER_TRACE | | PARAMETERS | | PARTITIONS | @@ -463,5 +469,5 @@ Wildcard: inf_rmation_schema | information_schema | SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 66 +information_schema 67 mysql 31 diff --git a/mysql-test/main/information_schema_db.result b/mysql-test/main/information_schema_db.result index 2b19415c05d..b5687956414 100644 --- a/mysql-test/main/information_schema_db.result +++ b/mysql-test/main/information_schema_db.result @@ -26,8 +26,6 @@ declare ret_val int; select max(f1) from t1 into ret_val; return ret_val; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create view v1 as select f1 from t1 where f1 = func1(f1); create function func2() returns int return 1; use mbase; diff --git a/mysql-test/main/innodb_ext_key,off.rdiff b/mysql-test/main/innodb_ext_key,off.rdiff index b334d006737..ef11f9c05bc 100644 --- a/mysql-test/main/innodb_ext_key,off.rdiff +++ b/mysql-test/main/innodb_ext_key,off.rdiff @@ -1,5 +1,5 @@ ---- innodb_ext_key.result -+++ innodb_ext_key,off.result +--- main/innodb_ext_key.result ++++ main/innodb_ext_key,off.reject @@ -9,7 +9,7 @@ explain select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01'; @@ -172,7 +172,7 @@ where l_partkey between 1 and 10 group by l_partkey; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE lineitem range i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 NULL # Using where; Using index for group-by -+1 SIMPLE lineitem range i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 NULL # Using where; Using index ++1 SIMPLE lineitem range i_l_suppkey_partkey,i_l_partkey i_l_suppkey_partkey 5 NULL # Using where; Using index flush status; select max(l_orderkey) from lineitem where l_partkey between 1 and 10 group by l_partkey; @@ -230,17 +230,17 @@ Handler_read_retry 0 Handler_read_rnd 0 @@ -314,8 +314,8 @@ - select * from t0, part ignore index (primary) + select straight_join * from t0, part ignore index (primary) where p_partkey=t0.a and p_size=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 ALL NULL NULL NULL NULL 5 Using where -1 SIMPLE part eq_ref i_p_size i_p_size 9 const,dbt3_s001.t0.a 1 +1 SIMPLE t0 ALL NULL NULL NULL NULL 5 +1 SIMPLE part ref i_p_size i_p_size 5 const 5 Using index condition - select * from t0, part ignore index (primary) + select straight_join * from t0, part ignore index (primary) where p_partkey=t0.a and p_size=1; a p_partkey p_name p_mfgr p_brand p_type p_size p_container p_retailprice p_comment -@@ -494,7 +494,7 @@ +@@ -495,7 +495,7 @@ select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where @@ -249,7 +249,7 @@ drop table t1,t2,t3; # # Bug mdev-4340: performance regression with extended_keys=on -@@ -714,13 +714,13 @@ +@@ -726,13 +726,13 @@ select * from t1 force index(index_date_updated) where index_date_updated= 10 and index_id < 800; id select_type table type possible_keys key key_len ref rows Extra @@ -265,7 +265,7 @@ drop table t0,t1,t2; # # MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff' -@@ -768,11 +768,12 @@ +@@ -770,11 +770,12 @@ { "table": { "table_name": "t1", @@ -278,10 +278,10 @@ + "key_length": "3066", + "used_key_parts": ["f2"], + "ref": ["const"], + "loops": 1, "rows": 1, - "filtered": 100, - "index_condition": "t1.pk1 <= 5 and t1.pk2 <= 5 and t1.f2 = 'abc'", -@@ -805,8 +806,8 @@ + "cost": "COST_REPLACED", +@@ -810,8 +811,8 @@ "access_type": "range", "possible_keys": ["k1"], "key": "k1", @@ -289,6 +289,6 @@ - "used_key_parts": ["pk1", "f2", "pk2"], + "key_length": "3007", + "used_key_parts": ["pk1", "f2"], + "loops": 1, "rows": 1, - "filtered": 100, - "index_condition": "t1.f2 <= 5 and t1.pk2 <= 5 and t1.pk1 = 'abc'", + "cost": "COST_REPLACED", diff --git a/mysql-test/main/innodb_ext_key.result b/mysql-test/main/innodb_ext_key.result index 02e199bc58a..d1f4c60f5b2 100644 --- a/mysql-test/main/innodb_ext_key.result +++ b/mysql-test/main/innodb_ext_key.result @@ -308,15 +308,15 @@ Handler_read_rnd_next 0 # when extended_keys=on # create table t0 (a int); -insert into t0 values (1), (2), (3), (4), (5); +insert into t0 select seq from seq_1_to_5; create index i_p_size on part(p_size); explain -select * from t0, part ignore index (primary) +select straight_join * from t0, part ignore index (primary) where p_partkey=t0.a and p_size=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 5 Using where 1 SIMPLE part eq_ref i_p_size i_p_size 9 const,dbt3_s001.t0.a 1 -select * from t0, part ignore index (primary) +select straight_join * from t0, part ignore index (primary) where p_partkey=t0.a and p_size=1; a p_partkey p_name p_mfgr p_brand p_type p_size p_container p_retailprice p_comment 2 2 blush rosy metallic lemon navajo Manufacturer#1 Brand#13 LARGE BRUSHED BRASS 1 LG CASE 902 final platelets hang f @@ -339,8 +339,8 @@ a b EXPLAIN SELECT * FROM t1 WHERE 2 IN (SELECT MAX(s1.a) FROM t1 AS s1, t1 AS s2); id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY const distinct_key distinct_key 4 const 1 -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) 2 MATERIALIZED s1 ALL NULL NULL NULL NULL 2 2 MATERIALIZED s2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) DROP TABLE t1; @@ -381,17 +381,18 @@ INSERT INTO t2 VALUES (10), (11), (12), (13), (14), (15), (16), (17), (18), (19), (24); EXPLAIN -SELECT a FROM t1 AS t, t2 -WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b); +SELECT a FROM t1 AS t, t2 as t2_out +WHERE t2_out.c = t.a AND t.b IN (SELECT b FROM t1, t2 WHERE b = t.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t index a,b b 7 NULL 10 Using index -1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t.a 1 Using index -1 PRIMARY t1 ref b b 3 test.t.b 2 Using index; Start temporary +1 PRIMARY t1 index b b 7 NULL 10 Using index; Start temporary +1 PRIMARY t ref a,b b 3 test.t1.b 2 Using index 1 PRIMARY t2 index NULL PRIMARY 4 NULL 11 Using index; End temporary; Using join buffer (flat, BNL join) -SELECT a FROM t1 AS t, t2 -WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b); +1 PRIMARY t2_out eq_ref PRIMARY PRIMARY 4 test.t.a 1 Using index +SELECT a FROM t1 AS t, t2 as t2_out +WHERE t2_out.c = t.a AND t.b IN (SELECT b FROM t1, t2 WHERE b = t.b); a 24 +Last_query_cost 0.120558 DROP TABLE t1,t2; # # LP Bug #923236: hash join + extended_keys = on @@ -645,7 +646,7 @@ a 2 explain select a from t2 where b is null order by a desc limit 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range b b 9 NULL 3 Using where; Using filesort +1 SIMPLE t2 index b PRIMARY 8 NULL 2 Using where select a from t2 where b is null order by a desc limit 2; a 3 @@ -758,12 +759,13 @@ PRIMARY KEY (pk1,pk2), KEY(f2) ) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); -explain format= json +explain format=json select * from t1 force index(f2) where pk1 <= 5 and pk2 <=5 and f2 = 'abc' and f1 <= '3'; EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -773,7 +775,9 @@ EXPLAIN "key": "f2", "key_length": "3070", "used_key_parts": ["f2", "pk1"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.pk1 <= 5 and t1.pk2 <= 5 and t1.f2 = 'abc'", "attached_condition": "t1.f1 <= '3'" @@ -792,12 +796,13 @@ PRIMARY KEY (pk1,pk2), KEY k1(pk1,f2) ) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); -explain format= json +explain format=json select * from t1 force index(k1) where f2 <= 5 and pk2 <=5 and pk1 = 'abc' and f1 <= '3'; EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -807,7 +812,9 @@ EXPLAIN "key": "k1", "key_length": "3011", "used_key_parts": ["pk1", "f2", "pk2"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.f2 <= 5 and t1.pk2 <= 5 and t1.pk1 = 'abc'", "attached_condition": "t1.f1 <= '3'" diff --git a/mysql-test/main/innodb_ext_key.test b/mysql-test/main/innodb_ext_key.test index 41a55232001..b14a5d5cab3 100644 --- a/mysql-test/main/innodb_ext_key.test +++ b/mysql-test/main/innodb_ext_key.test @@ -4,6 +4,7 @@ --source include/innodb_prefix_index_cluster_optimization.inc --source include/no_valgrind_without_big.inc +--source include/have_sequence.inc SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; @@ -156,14 +157,14 @@ show status like 'handler_read%'; --echo # create table t0 (a int); -insert into t0 values (1), (2), (3), (4), (5); +insert into t0 select seq from seq_1_to_5; create index i_p_size on part(p_size); explain -select * from t0, part ignore index (primary) +select straight_join * from t0, part ignore index (primary) where p_partkey=t0.a and p_size=1; -select * from t0, part ignore index (primary) +select straight_join * from t0, part ignore index (primary) where p_partkey=t0.a and p_size=1; drop table t0; @@ -240,10 +241,11 @@ INSERT INTO t2 VALUES (15), (16), (17), (18), (19), (24); EXPLAIN -SELECT a FROM t1 AS t, t2 - WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b); -SELECT a FROM t1 AS t, t2 - WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b); +SELECT a FROM t1 AS t, t2 as t2_out + WHERE t2_out.c = t.a AND t.b IN (SELECT b FROM t1, t2 WHERE b = t.b); +SELECT a FROM t1 AS t, t2 as t2_out + WHERE t2_out.c = t.a AND t.b IN (SELECT b FROM t1, t2 WHERE b = t.b); +--source include/last_query_cost.inc DROP TABLE t1,t2; @@ -612,7 +614,8 @@ CREATE TABLE t1 ( ) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); -explain format= json +--source include/explain-no-costs.inc +explain format=json select * from t1 force index(f2) where pk1 <= 5 and pk2 <=5 and f2 = 'abc' and f1 <= '3'; drop table t1; @@ -625,7 +628,8 @@ PRIMARY KEY (pk1,pk2), KEY k1(pk1,f2) ) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); -explain format= json +--source include/explain-no-costs.inc +explain format=json select * from t1 force index(k1) where f2 <= 5 and pk2 <=5 and pk1 = 'abc' and f1 <= '3'; drop table t1; diff --git a/mysql-test/main/innodb_icp.result b/mysql-test/main/innodb_icp.result index c89d49cad0c..bdbc2f6ccc1 100644 --- a/mysql-test/main/innodb_icp.result +++ b/mysql-test/main/innodb_icp.result @@ -437,7 +437,7 @@ WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10 id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where 2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func # Using where -2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL # Using index; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10); pk i @@ -455,9 +455,10 @@ c1 INT NOT NULL, PRIMARY KEY (pk) ); INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1); +insert into t1 select seq,seq from seq_100_to_110; EXPLAIN SELECT pk, c1 FROM t1 WHERE (pk<3 or pk>3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 15 Using where SET SESSION optimizer_switch='index_condition_pushdown=off'; SELECT pk, c1 FROM t1 WHERE (pk<3 or pk>3); pk c1 @@ -465,6 +466,17 @@ pk c1 2 7 4 3 5 1 +100 100 +101 101 +102 102 +103 103 +104 104 +105 105 +106 106 +107 107 +108 108 +109 109 +110 110 DROP TABLE t1; set optimizer_switch= @save_optimizer_switch; # @@ -682,7 +694,6 @@ DROP TABLE t1; # CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b)); INSERT INTO t1 VALUES (1,4,'Ill'); -insert into t1 select seq+100,5,seq from seq_1_to_100; CREATE TABLE t2 (a varchar(1024), KEY (a(512))); INSERT INTO t2 VALUES ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w'); @@ -816,6 +827,8 @@ test.t2 analyze status Engine-independent statistics collected test.t2 analyze status OK SET @save_optimize_switch=@@optimizer_switch; SET optimizer_switch='materialization=on'; +set @save_optimizer_where_cost=@@optimizer_where_cost; +set @@optimizer_where_cost=1; EXPLAIN SELECT COUNT(*) FROM t1 AS t, t2 WHERE c = g @@ -839,6 +852,7 @@ OR a = 0 AND h < 'z' ); COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; +set @@optimizer_where_cost=@save_optimizer_where_cost; DROP TABLE t1,t2; # check "Handler_pushed" status varuiables CREATE TABLE t1 ( diff --git a/mysql-test/main/innodb_mysql_lock2.result b/mysql-test/main/innodb_mysql_lock2.result index ffbe3f8a406..9dd5bddc085 100644 --- a/mysql-test/main/innodb_mysql_lock2.result +++ b/mysql-test/main/innodb_mysql_lock2.result @@ -57,8 +57,6 @@ declare j int; select i from t1 where i = 1 into j; return j; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f2() returns int begin declare k int; @@ -66,8 +64,6 @@ select i from t1 where i = 1 into k; insert into t2 values (k + 5); return 0; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f3() returns int begin return (select i from t1 where i = 3); @@ -91,16 +87,12 @@ declare k int; select i from v1 where i = 1 into k; return k; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f7() returns int begin declare k int; select j from v2 where j = 1 into k; return k; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f8() returns int begin declare k int; @@ -108,8 +100,6 @@ select i from v1 where i = 1 into k; insert into t2 values (k+5); return k; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f9() returns int begin update v2 set j=j+10 where j=1; @@ -139,8 +129,6 @@ create procedure p2(inout p int) begin select i from t1 where i = 1 into p; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f14() returns int begin declare k int; @@ -160,8 +148,6 @@ declare k int; select i from t1 where i=1 into k; set new.l= k+1; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create trigger t4_bu before update on t4 for each row begin if (select i from t1 where i=1) then diff --git a/mysql-test/main/innodb_mysql_lock2.test b/mysql-test/main/innodb_mysql_lock2.test index 09298a900b1..e5bb4bd9565 100644 --- a/mysql-test/main/innodb_mysql_lock2.test +++ b/mysql-test/main/innodb_mysql_lock2.test @@ -833,6 +833,7 @@ insert into t1 values (1), (2), (3), (4), (5); begin; --echo # Acquire SR metadata lock on t1. +--sorted_result select * from t1; connection con1; diff --git a/mysql-test/main/intersect.result b/mysql-test/main/intersect.result index 425f6940a35..83a607f4e45 100644 --- a/mysql-test/main/intersect.result +++ b/mysql-test/main/intersect.result @@ -51,12 +51,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -67,12 +70,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "INTERSECT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -83,12 +89,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -115,6 +124,7 @@ ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -122,9 +132,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -138,6 +150,7 @@ ANALYZE "query_block": { "select_id": 2, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -145,9 +158,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -161,6 +176,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -168,9 +184,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -192,6 +210,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -199,9 +218,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -217,6 +238,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -224,9 +246,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -240,6 +264,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -247,9 +272,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -263,6 +290,7 @@ ANALYZE "query_block": { "select_id": 4, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -270,9 +298,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -346,12 +376,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -362,12 +395,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "INTERSECT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -376,7 +412,9 @@ EXPLAIN "table": { "table_name": "t3", "access_type": "ALL", + "loops": 3, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -407,6 +445,7 @@ ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -414,9 +453,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -430,6 +471,7 @@ ANALYZE "query_block": { "select_id": 2, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -437,9 +479,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -451,9 +495,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 3, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -462,7 +508,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "256Kb", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -480,6 +527,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -487,9 +535,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -505,6 +555,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -512,9 +563,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -528,6 +581,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -535,9 +589,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -549,9 +605,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 3, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -560,7 +618,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "256Kb", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] diff --git a/mysql-test/main/intersect.test b/mysql-test/main/intersect.test index 5e811f1f56d..30f99b20aa2 100644 --- a/mysql-test/main/intersect.test +++ b/mysql-test/main/intersect.test @@ -23,6 +23,7 @@ insert into t3 values (1,1),(2,2),(5,5); EXPLAIN (select a,b from t1) intersect (select c,d from t2) intersect (select e,f from t3); EXPLAIN extended (select a,b from t1) intersect (select c,d from t2) intersect (select e,f from t3); EXPLAIN extended select * from ((select a,b from t1) intersect (select c,d from t2) intersect (select e,f from t3)) a; +--source include/explain-no-costs.inc EXPLAIN format=json (select a,b from t1) intersect (select c,d from t2) intersect (select e,f from t3); --source include/analyze-format.inc ANALYZE format=json (select a,b from t1) intersect (select c,d from t2) intersect (select e,f from t3); @@ -43,6 +44,7 @@ EXPLAIN (select a,b from t1) intersect (select c,e from t2,t3); EXPLAIN extended (select a,b from t1) intersect (select c,e from t2,t3); EXPLAIN extended select * from ((select a,b from t1) intersect (select c,e from t2,t3)) a; set @@optimizer_switch='optimize_join_buffer_size=off'; +--source include/explain-no-costs.inc EXPLAIN format=json (select a,b from t1) intersect (select c,e from t2,t3); --source include/analyze-format.inc ANALYZE format=json (select a,b from t1) intersect (select c,e from t2,t3); diff --git a/mysql-test/main/intersect_all.result b/mysql-test/main/intersect_all.result index aecd5b1ac18..8f826a193aa 100644 --- a/mysql-test/main/intersect_all.result +++ b/mysql-test/main/intersect_all.result @@ -63,12 +63,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -79,12 +82,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "INTERSECT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -95,12 +101,15 @@ EXPLAIN "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -127,6 +136,7 @@ ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -134,9 +144,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -150,6 +162,7 @@ ANALYZE "query_block": { "select_id": 2, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -157,9 +170,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -173,6 +188,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -180,9 +196,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -204,6 +222,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -211,9 +230,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -229,6 +250,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -236,9 +258,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -252,6 +276,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -259,9 +284,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -275,6 +302,7 @@ ANALYZE "query_block": { "select_id": 4, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -282,9 +310,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -377,12 +407,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 6, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -393,12 +426,15 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "INTERSECT", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -407,7 +443,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 5, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -438,6 +476,7 @@ ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -445,9 +484,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 6, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -461,6 +502,7 @@ ANALYZE "query_block": { "select_id": 2, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -468,9 +510,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 5, "r_rows": 5, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -482,9 +526,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 5, "r_loops": 1, "rows": 7, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -493,7 +539,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "65", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -511,6 +558,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -518,9 +566,11 @@ ANALYZE "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 6, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -536,6 +586,7 @@ ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -543,9 +594,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 6, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -559,6 +612,7 @@ ANALYZE "query_block": { "select_id": 3, "operation": "INTERSECT", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -566,9 +620,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 5, "r_rows": 5, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -580,9 +636,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 5, "r_loops": 1, "rows": 7, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -591,7 +649,8 @@ ANALYZE "buffer_type": "flat", "buffer_size": "65", "join_type": "BNL", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] diff --git a/mysql-test/main/intersect_all.test b/mysql-test/main/intersect_all.test index 5d2b038fde9..769b25393dd 100644 --- a/mysql-test/main/intersect_all.test +++ b/mysql-test/main/intersect_all.test @@ -22,6 +22,7 @@ insert into t3 values (1,1),(2,2),(5,5),(2,2); EXPLAIN (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3); EXPLAIN extended (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3); EXPLAIN extended select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a; +--source include/explain-no-costs.inc EXPLAIN format=json (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3); --source include/analyze-format.inc ANALYZE format=json (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3); @@ -50,6 +51,7 @@ insert into t3 values (2,2); EXPLAIN (select a,b from t1) intersect all (select c,e from t2,t3); EXPLAIN extended (select a,b from t1) intersect all (select c,e from t2,t3); EXPLAIN extended select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a; +--source include/explain-no-costs.inc EXPLAIN format=json (select a,b from t1) intersect all (select c,e from t2,t3); --source include/analyze-format.inc ANALYZE format=json (select a,b from t1) intersect all (select c,e from t2,t3); @@ -325,4 +327,4 @@ select * from t2 where a < 5 intersect all select * from t3 where a < 5; -drop table t1,t2,t3; \ No newline at end of file +drop table t1,t2,t3; diff --git a/mysql-test/main/invisible_field.result b/mysql-test/main/invisible_field.result index 7aa88e7787e..988f8524345 100644 --- a/mysql-test/main/invisible_field.result +++ b/mysql-test/main/invisible_field.result @@ -559,8 +559,6 @@ DROP TABLE t1; create or replace table t1 (a int, b int invisible); insert into t1 values (1),(2); select * from t1 into outfile 'f'; -Warnings: -Warning 1287 ' INTO FROM...' instead load data infile 'f' into table t1; select a,b from t1; a b @@ -591,8 +589,6 @@ a b truncate table t1; insert into t1(a,b) values (1,1),(2,2); select a,b from t1 into outfile 'a'; -Warnings: -Warning 1287 ' INTO FROM...' instead load data infile 'a' into table t1(a,b); select a,b from t1; a b diff --git a/mysql-test/main/invisible_field_debug.result b/mysql-test/main/invisible_field_debug.result index 344a0b860fc..8cc1ee4db9c 100644 --- a/mysql-test/main/invisible_field_debug.result +++ b/mysql-test/main/invisible_field_debug.result @@ -346,7 +346,7 @@ invisible a b 9 7 7 explain select * from t1 where invisible =9; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL invisible NULL NULL NULL 7 Using where +1 SIMPLE t1 ref invisible invisible 5 const 7 alter table t1 add x int default 3; select invisible, a ,b from t1; invisible a b @@ -368,11 +368,11 @@ drop index invisible on t1; ERROR 42000: Can't DROP INDEX `invisible`; check that it exists explain select * from t1 where invisible =9; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL invisible NULL NULL NULL 7 Using where +1 SIMPLE t1 ref invisible invisible 5 const 7 create index invisible on t1(c); explain select * from t1 where invisible =9; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL invisible_2 NULL NULL NULL 7 Using where +1 SIMPLE t1 ref invisible_2 invisible_2 5 const 7 show indexes in t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored t1 1 b 1 b A NULL NULL NULL YES BTREE NO diff --git a/mysql-test/main/join.result b/mysql-test/main/join.result index 59d6ae98ff3..a6c2f88b841 100644 --- a/mysql-test/main/join.result +++ b/mysql-test/main/join.result @@ -65,7 +65,7 @@ id id NULL 75 explain select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 const PRIMARY NULL NULL NULL 1 Impossible ON condition +1 SIMPLE t1 const PRIMARY NULL NULL NULL 0 Impossible ON condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where explain select t1.id, t2.id from t1, t2 where t2.id = t1.id and t1.id <0 and t1.id > 0; id select_type table type possible_keys key key_len ref rows Extra @@ -258,7 +258,7 @@ name varchar(255) default NULL, PRIMARY KEY (id) ) ENGINE=MyISAM; INSERT INTO t2 VALUES (1,'s1'),(2,'s2'),(3,'s3'),(4,'s4'),(5,'s5'); -select t1.*, t2.* from t1, t2 where t2.id=t1.t2_id limit 2; +select straight_join t1.*, t2.* from t2, t1 where t2.id=t1.t2_id limit 2; t1_id t2_id type cost_unit min_value max_value t3_id item_id id name 12 5 Percent Cost -1 0 -1 -1 5 s5 14 4 Percent Cost -1 0 -1 -1 4 s4 @@ -883,7 +883,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL a,b NULL NULL NULL 1000 Using where 1 SIMPLE t3 ref b b 5 test.t2.b 1 drop table t1, t2, t3; -create table t1 (a int); +create table t1 (a int) engine=myisam; insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t2 (a int, b int, primary key(a)); insert into t2 select @v:=A.a+10*B.a, @v from t1 A, t1 B; @@ -892,13 +892,17 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 4.016090 +Last_query_cost 0.011600 select 'The cost of accessing t1 (dont care if it changes' '^'; The cost of accessing t1 (dont care if it changes The cost of accessing t1 (dont care if it changes^ select 'vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv' Z; Z vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv +select @@myisam.optimizer_disk_read_ratio; +@@myisam.optimizer_disk_read_ratio +0.020000 +set global myisam.optimizer_disk_read_ratio=0; explain select * from t1, t2 A, t2 B where A.a = t1.a and B.a=A.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where @@ -906,10 +910,14 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE B eq_ref PRIMARY PRIMARY 4 test.A.b 1 show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 28.016090 -select '^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error' Z; +Last_query_cost 0.046590 +select '^^: The above should be ~= 40 + cost(select * from t1). Value less than 40 is an error' Z; Z -^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error +^^: The above should be ~= 40 + cost(select * from t1). Value less than 40 is an error +set global myisam.optimizer_disk_read_ratio=default; +select @@myisam.optimizer_disk_read_ratio; +@@myisam.optimizer_disk_read_ratio +0.020000 drop table t1, t2; CREATE TABLE t1 (a INT PRIMARY KEY, b INT); CREATE TABLE t2 (c INT PRIMARY KEY, d INT); @@ -1107,7 +1115,7 @@ ON t4.a = t5.a ON t1.a = t3.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 -1 SIMPLE t3 ref a a 5 test.t1.a 2 Using where; Using index +1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where; Using index 1 SIMPLE t4 ALL NULL NULL NULL NULL 0 Using where 1 SIMPLE t5 ALL NULL NULL NULL NULL 0 Using where 1 SIMPLE t6 ALL NULL NULL NULL NULL 0 Using where @@ -1274,13 +1282,17 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK test.t2 analyze status Engine-independent statistics collected test.t2 analyze status OK +explain SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref ix2 ix2 5 const 2 Using index condition; Using temporary; Using filesort +1 SIMPLE t1 ref ix1 ix1 5 test.t2.v 1 FLUSH STATUS; SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1; pk v pk v SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value Handler_read_first 0 -Handler_read_key 14 +Handler_read_key 1 Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 @@ -1323,9 +1335,9 @@ FROM t4 JOIN (t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1) ON t4.ref_t1=t1.c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL NULL NULL NULL NULL 4 -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t4.ref_t1 1 +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) EXPLAIN SELECT * @@ -1334,9 +1346,9 @@ FROM t4 STRAIGHT_JOIN ON t4.ref_t1=t1.c1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 4 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t4.ref_t1 1 -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) drop table t1,t2,t3,t4; End of 5.2 tests # @@ -1474,7 +1486,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE D system PRIMARY NULL NULL NULL 1 1 SIMPLE DSAR system NULL NULL NULL NULL 1 1 SIMPLE DSA ref PRIMARY PRIMARY 4 const 3 Using where; Using index -1 SIMPLE DT ALL t_id NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +1 SIMPLE DT ref t_id t_id 2 test.DSA.t_id 1 Using where SELECT * FROM t5 DU, t1 D, t4 DT, t2 DSA, t3 DSAR WHERE DU.dog_id=D.dog_id AND D.dog_id=DT.dog_id AND D.birthday=DT.birthday AND DT.t_id=DSA.t_id AND DT.birthday=DSA.birthday AND DSA.dog_id=DSAR.dog_id; @@ -3424,3 +3436,24 @@ COUNT(*) 2 DROP TABLE t1, t2, t3; # End of 10.5 tests +# +# MDEV-30256 Wrong result (missing rows) upon join with empty table +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t3 (c INT PRIMARY KEY); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON (t2.b >= t3.c) ON (t1.a < t2.b); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 0 Using index; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) +SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON (t2.b >= t3.c) ON (t1.a < t2.b); +a b c +1 NULL NULL +2 NULL NULL +DROP TABLE t1,t2,t3; +# +# End of 11.0 tests +# diff --git a/mysql-test/main/join.test b/mysql-test/main/join.test index 1668787d33e..453cf8c2313 100644 --- a/mysql-test/main/join.test +++ b/mysql-test/main/join.test @@ -253,7 +253,7 @@ CREATE TABLE t2 ( PRIMARY KEY (id) ) ENGINE=MyISAM; INSERT INTO t2 VALUES (1,'s1'),(2,'s2'),(3,'s3'),(4,'s4'),(5,'s5'); -select t1.*, t2.* from t1, t2 where t2.id=t1.t2_id limit 2; +select straight_join t1.*, t2.* from t2, t1 where t2.id=t1.t2_id limit 2; drop table t1,t2; # @@ -685,7 +685,7 @@ drop table t1, t2, t3; # BUG#14940 {Wrong query plan is chosen because of odd results of # prev_record_reads() function } -create table t1 (a int); +create table t1 (a int) engine=myisam; insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t2 (a int, b int, primary key(a)); @@ -697,12 +697,13 @@ select 'The cost of accessing t1 (dont care if it changes' '^'; select 'vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv' Z; +select @@myisam.optimizer_disk_read_ratio; +set global myisam.optimizer_disk_read_ratio=0; explain select * from t1, t2 A, t2 B where A.a = t1.a and B.a=A.b; show status like 'Last_query_cost'; -select '^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error' Z; - - - +select '^^: The above should be ~= 40 + cost(select * from t1). Value less than 40 is an error' Z; +set global myisam.optimizer_disk_read_ratio=default; +select @@myisam.optimizer_disk_read_ratio; drop table t1, t2; # @@ -957,6 +958,9 @@ INSERT INTO t1 VALUES (3,'b'),(4,NULL),(5,'c'),(6,'cc'),(7,'d'), (8,'dd'),(9,'e'),(10,'ee'); INSERT INTO t2 VALUES (2,NULL); ANALYZE TABLE t1,t2; +# This will ensure that status tables are read now and not part of the later +# Handler_read% counts +explain SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1; FLUSH STATUS; SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1; SHOW STATUS LIKE 'Handler_read_%'; @@ -1835,3 +1839,20 @@ SELECT COUNT(*) FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2. DROP TABLE t1, t2, t3; --echo # End of 10.5 tests + +--echo # +--echo # MDEV-30256 Wrong result (missing rows) upon join with empty table +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t3 (c INT PRIMARY KEY); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON (t2.b >= t3.c) ON (t1.a < t2.b); +SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON (t2.b >= t3.c) ON (t1.a < t2.b); +DROP TABLE t1,t2,t3; + +--echo # +--echo # End of 11.0 tests +--echo # diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result index 938167035a2..0965ac8a555 100644 --- a/mysql-test/main/join_cache.result +++ b/mysql-test/main/join_cache.result @@ -53,6 +53,7 @@ set join_cache_level=1; show variables like 'join_cache_level'; Variable_name Value join_cache_level 1 +# Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -60,6 +61,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join) +# Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -79,6 +81,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -91,6 +94,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join) 1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join) +# Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -131,6 +135,7 @@ set join_cache_level=2; show variables like 'join_cache_level'; Variable_name Value join_cache_level 2 +# join_cache_level 2, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -138,6 +143,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join) +# join_cache_level 2, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -157,6 +163,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# join_cache_level 2, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -169,6 +176,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join) 1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (incremental, BNL join) +# join_cache_level 2, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -209,6 +217,7 @@ set join_cache_level=3; show variables like 'join_cache_level'; Variable_name Value join_cache_level 3 +# join_cache_level 3, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -216,6 +225,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# join_cache_level 3, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -235,6 +245,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# join_cache_level 3, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -247,6 +258,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# join_cache_level 3, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -287,6 +299,7 @@ set join_cache_level=4; show variables like 'join_cache_level'; Variable_name Value join_cache_level 4 +# join_cache_level 4, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -294,6 +307,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# join_cache_level 4, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -313,6 +327,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# join_cache_level 4, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -325,6 +340,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (incremental, BNLH join) +# join_cache_level 4, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -361,6 +377,7 @@ Ludwigshafen am Rhein Germany German Lungtan Taiwan Min L´Hospitalet de Llobregat Spain Spanish Lázaro Cárdenas Mexico Spanish +# join_cache_level 4, Query 5 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND City.Population > 5000000 @@ -379,6 +396,7 @@ Canada 31147000 NULL NULL Cuba 11201000 NULL NULL Côte d?Ivoire 14786000 NULL NULL Czech Republic 10278100 NULL NULL +# join_cache_level 4, Query 6 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND @@ -404,6 +422,7 @@ Czech Republic 10278100 NULL NULL CREATE INDEX City_Population ON City(Population); CREATE INDEX City_Name ON City(Name); ANALYZE TABLE City; +# After Analyze, Query 1 EXPLAIN SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City @@ -412,6 +431,7 @@ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City hash_range City_Population #hash#$hj:City_Population 3:4 world.Country.Code 24 Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join) +# After Analyze, Query 2 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND City.Population > 5000000 @@ -430,6 +450,7 @@ Canada 31147000 NULL NULL Cuba 11201000 NULL NULL Côte d?Ivoire 14786000 NULL NULL Czech Republic 10278100 NULL NULL +# After Analyze, Query 3 EXPLAIN SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City @@ -439,6 +460,7 @@ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City hash_index_merge City_Population,City_Name #hash#$hj:City_Population,City_Name 3:4,35 world.Country.Code 96 Using sort_union(City_Population,City_Name); Using where; Using join buffer (flat, BNLH join) +# After Analyze, Query 4 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND @@ -471,6 +493,7 @@ join_buffer_size 256 show variables like 'join_cache_level'; Variable_name Value join_cache_level 1 +# join_cache_level 1, Join_buffer_size, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -478,6 +501,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join) +# join_cache_level 1, Join_buffer_size, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -497,6 +521,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# join_cache_level 1, Join_buffer_size, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -509,6 +534,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join) 1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join) +# join_cache_level 1, Join_buffer_size, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -549,6 +575,7 @@ set join_cache_level=2; show variables like 'join_cache_level'; Variable_name Value join_cache_level 2 +# join_cache_level 2, Join_buffer_size, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -556,6 +583,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (flat, BNL join) +# join_cache_level 2, Join_buffer_size, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -575,6 +603,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# join_cache_level 2, Join_buffer_size, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -587,6 +616,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 Using where; Using join buffer (flat, BNL join) 1 SIMPLE City ALL NULL NULL NULL NULL 4079 Using where; Using join buffer (incremental, BNL join) +# join_cache_level 2, Join_buffer_size, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -627,6 +657,7 @@ set join_cache_level=3; show variables like 'join_cache_level'; Variable_name Value join_cache_level 3 +# join_cache_level 3, Join_buffer_size, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -634,6 +665,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# join_cache_level 3, Join_buffer_size, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -653,6 +685,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# join_cache_level 3, Join_buffer_size, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -665,6 +698,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# join_cache_level 3, Join_buffer_size, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -705,6 +739,7 @@ set join_cache_level=4; show variables like 'join_cache_level'; Variable_name Value join_cache_level 4 +# join_cache_level 4, Join_buffer_size, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -712,6 +747,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# join_cache_level 4, Join_buffer_size, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -731,6 +767,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# join_cache_level 4, Join_buffer_size, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -743,6 +780,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (incremental, BNLH join) +# join_cache_level 4, Join_buffer_size, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -816,6 +854,7 @@ set join_cache_level=3; show variables like 'join_cache_level'; Variable_name Value join_cache_level 3 +# Part 2, join_cache_level=3, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -823,6 +862,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Rowid-ordered scan 1 SIMPLE City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# Part 2, join_cache_level=3, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -842,6 +882,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# Part 2, join_cache_level=3, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -854,6 +895,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where 1 SIMPLE Country hash_ALL PRIMARY #hash#PRIMARY 3 world.City.Country 239 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE CountryLanguage hash_ALL|filter PRIMARY,Percentage #hash#PRIMARY|Percentage 3|4 world.City.Country 984 (19%) Using where; Using join buffer (flat, BNLH join); Using rowid filter +# Part 2, join_cache_level=3, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -890,6 +932,7 @@ Ludwigshafen am Rhein Germany German Lungtan Taiwan Min L´Hospitalet de Llobregat Spain Spanish Lázaro Cárdenas Mexico Spanish +# Part 2, join_cache_level=3, Query 5 EXPLAIN SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND @@ -897,6 +940,7 @@ City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Rowid-ordered scan 1 PRIMARY City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# Part 2, join_cache_level=3, Query 6 SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND City.Population > 100000; @@ -916,6 +960,7 @@ Kaunas Klaipeda ?iauliai Panevezys +# Part 2, join_cache_level=3, Query 7 EXPLAIN SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) FROM Country LEFT JOIN CountryLanguage ON @@ -925,6 +970,7 @@ Country.Population > 10000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage hash_ALL PRIMARY #hash#PRIMARY 33 world.Country.Code,const 984 Using where; Using join buffer (flat, BNLH join) +# Part 2, join_cache_level=3, Query 8 SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) FROM Country LEFT JOIN CountryLanguage ON (CountryLanguage.Country=Country.Code AND Language='English') @@ -1016,6 +1062,7 @@ set join_cache_level=4; show variables like 'join_cache_level'; Variable_name Value join_cache_level 4 +# Part 2, join_cache_level=4, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND @@ -1023,6 +1070,7 @@ Country.Name LIKE 'L%' AND City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Rowid-ordered scan 1 SIMPLE City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# Part 2, join_cache_level=4, Query 2 SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; @@ -1042,6 +1090,7 @@ Tripoli Lebanon Tripoli Libyan Arab Jamahiriya Vientiane Laos Vilnius Lithuania +# Part 2, join_cache_level=4, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -1054,6 +1103,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where 1 SIMPLE Country hash_ALL PRIMARY #hash#PRIMARY 3 world.City.Country 239 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE CountryLanguage hash_ALL|filter PRIMARY,Percentage #hash#PRIMARY|Percentage 3|4 world.City.Country 984 (19%) Using where; Using join buffer (incremental, BNLH join); Using rowid filter +# Part 2, join_cache_level=4, Query 4 SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND @@ -1090,6 +1140,7 @@ Ludwigshafen am Rhein Germany German Lungtan Taiwan Min L´Hospitalet de Llobregat Spain Spanish Lázaro Cárdenas Mexico Spanish +# Part 2, join_cache_level=4, Query 5 EXPLAIN SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND @@ -1097,6 +1148,7 @@ City.Population > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Rowid-ordered scan 1 PRIMARY City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join) +# Part 2, join_cache_level=4, Query 6 SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND City.Population > 100000; @@ -1116,6 +1168,7 @@ Kaunas Klaipeda ?iauliai Panevezys +# Part 2, join_cache_level=4, Query 7 EXPLAIN SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) FROM Country LEFT JOIN CountryLanguage ON @@ -1125,6 +1178,7 @@ Country.Population > 10000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country ALL NULL NULL NULL NULL 239 Using where 1 SIMPLE CountryLanguage hash_ALL PRIMARY #hash#PRIMARY 33 world.Country.Code,const 984 Using where; Using join buffer (flat, BNLH join) +# Part 2, join_cache_level=4, Query 8 SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) FROM Country LEFT JOIN CountryLanguage ON (CountryLanguage.Country=Country.Code AND Language='English') @@ -1209,6 +1263,7 @@ Belarus NULL Venezuela NULL Russian Federation NULL Vietnam NULL +# Part 2, join_cache_level=4, Query 9 EXPLAIN SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City @@ -1217,6 +1272,7 @@ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country range Name Name 52 NULL # Using index condition; Using where; Rowid-ordered scan 1 SIMPLE City hash_range Population,Country #hash#Country:Population 3:4 world.Country.Code # Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join) +# Part 2, join_cache_level=4, Query 10 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND City.Population > 5000000 @@ -1236,6 +1292,7 @@ Cuba 11201000 NULL NULL Côte d?Ivoire 14786000 NULL NULL Czech Republic 10278100 NULL NULL CREATE INDEX City_Name ON City(Name); +# Part 2, join_cache_level=4, City_Name, Query 1 EXPLAIN SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City @@ -1245,6 +1302,7 @@ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Country range Name Name 52 NULL 17 Using index condition; Using where; Rowid-ordered scan 1 SIMPLE City hash_index_merge Population,Country,City_Name #hash#Country:Population,City_Name 3:4,35 world.Country.Code 96 Using sort_union(Population,City_Name); Using where; Using join buffer (flat, BNLH join) +# Part 2, join_cache_level=4, City_Name, Query 2 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND @@ -3067,13 +3125,13 @@ t1.metaid = t2.metaid AND t1.affiliateid = '2'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t6 system PRIMARY NULL NULL NULL 1 1 SIMPLE t5 ref PRIMARY,t5_formattypeid t5_formattypeid 4 const 1 -1 SIMPLE t1 ref t1_affiliateid,t1_metaid t1_affiliateid 4 const 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t7 ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using index +1 SIMPLE t4 ref PRIMARY,t4_formatclassid,t4_formats_idx t4_formatclassid 4 test.t5.formatclassid 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 ref t3_metaid,t3_formatid,t3_metaidformatid t3_formatid 4 test.t4.formatid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t1 ref t1_affiliateid,t1_metaid t1_metaid 4 test.t3.metaid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.metaid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t7 ref PRIMARY PRIMARY 4 test.t3.metaid 1 Using index 1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t3 ref t3_metaid,t3_formatid,t3_metaidformatid t3_metaidformatid 4 test.t1.metaid 1 Using index condition; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t4 eq_ref PRIMARY,t4_formatclassid,t4_formats_idx PRIMARY 4 test.t3.formatid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t9 index PRIMARY,t9_subgenreid,t9_metaid PRIMARY 8 NULL 2 Using where; Using index; Using join buffer (incremental, BNL join) +1 SIMPLE t9 ref PRIMARY,t9_subgenreid,t9_metaid t9_metaid 4 test.t3.metaid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t10 eq_ref PRIMARY,t10_genreid PRIMARY 4 test.t9.subgenreid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t10.genreid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan SELECT t1.uniquekey, t1.xml AS affiliateXml, @@ -3215,7 +3273,7 @@ EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref i_a i_a 4 test.t1.a 2 Using where; Not exists +1 SIMPLE t2 ref i_a i_a 4 test.t1.a 1 Using where; Not exists SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL; a a b 3 NULL NULL @@ -3226,7 +3284,7 @@ EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref i_a i_a 4 test.t1.a 2 Using where; Not exists; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref i_a i_a 4 test.t1.a 1 Using where; Not exists; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL; a a b 3 NULL NULL @@ -3253,7 +3311,7 @@ select t1.a, count(t2.p) as count from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL 8 Using index; Using temporary; Using filesort -1 SIMPLE t2 ref i_a i_a 5 test.t1.a 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref i_a i_a 5 test.t1.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan select t1.a, count(t2.p) as count from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a; a count @@ -3371,8 +3429,8 @@ set join_cache_level=6; set join_buffer_size=1024; EXPLAIN SELECT AVG(c) FROM t1,t2 WHERE t1.a=t2.b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 2050 Using where -1 SIMPLE t2 ref idx idx 5 test.t1.a 640 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ALL idx NULL NULL NULL 1280 Using where +1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t2.b 2050 Using where; Using join buffer (flat, BNLH join) SELECT AVG(c) FROM t1,t2 WHERE t1.a=t2.b; AVG(c) 5.0000 @@ -4027,7 +4085,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.carrier 1 Using where -1 SIMPLE t4 ref carrier_id carrier_id 5 test.t3.id 2 Using index +1 SIMPLE t4 ref carrier_id carrier_id 5 test.t3.id 1 Using index SET join_cache_level=@save_join_cache_level; DROP TABLE t1,t2,t3,t4; # @@ -4043,7 +4101,7 @@ set join_cache_level = 5; explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 -1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref b b 5 test.t1.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; a NULL @@ -4052,7 +4110,7 @@ set join_cache_level = 8; explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 -1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref b b 5 test.t1.b 1 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; a NULL @@ -4063,7 +4121,7 @@ set join_cache_level = 5; explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 -1 SIMPLE t2 ref b b 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref b b 5 test.t1.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; a NULL @@ -4078,7 +4136,7 @@ set join_cache_level = 5; explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 -1 SIMPLE t2 ref b b 103 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref b b 103 test.t1.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; a NULL @@ -4087,7 +4145,7 @@ set join_cache_level = 8; explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 -1 SIMPLE t2 ref b b 103 test.t1.b 2 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref b b 103 test.t1.b 1 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; a NULL @@ -4340,9 +4398,9 @@ SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort +1 SIMPLE t1 ALL idx2 NULL NULL NULL 44 Using where; Using temporary; Using filesort +1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using where; Using index; Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where -1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; @@ -4357,9 +4415,9 @@ SELECT t2.v FROM t1, t2, t3 WHERE t2.v <> t3.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort +1 SIMPLE t1 ALL idx2 NULL NULL NULL 44 Using where; Using temporary; Using filesort +1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using where; Using index; Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where -1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where SELECT t2.v FROM t1, t2, t3 WHERE t2.v <> t3.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; @@ -4375,9 +4433,9 @@ SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort -1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t1 ALL idx2 NULL NULL NULL 44 Using where; Using temporary; Using filesort +1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using where; Using index; Using join buffer (flat, BNL join) +1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; @@ -4392,9 +4450,9 @@ SELECT t2.v FROM t1, t2, t3 WHERE t2.v <> t3.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort -1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t1 ALL idx2 NULL NULL NULL 44 Using where; Using temporary; Using filesort +1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using where; Using index; Using join buffer (flat, BNL join) +1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan SELECT t2.v FROM t1, t2, t3 WHERE t2.v <> t3.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; @@ -4410,9 +4468,9 @@ SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort -1 SIMPLE t3 hash_ALL PRIMARY,idx2 #hash#PRIMARY 4 test.t2.i 20 Using where; Using join buffer (flat, BNLH join) -1 SIMPLE t1 hash_ALL idx2 #hash#idx2 3 test.t3.v 44 Using where; Using join buffer (incremental, BNLH join) +1 SIMPLE t1 ALL idx2 NULL NULL NULL 44 Using where; Using temporary; Using filesort +1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using where; Using index; Using join buffer (flat, BNL join) +1 SIMPLE t3 hash_ALL PRIMARY,idx2 #hash#PRIMARY 4 test.t2.i 20 Using where; Using join buffer (incremental, BNLH join) SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; @@ -4427,9 +4485,9 @@ SELECT t2.v FROM t1, t2, t3 WHERE t2.v <> t3.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort -1 SIMPLE t3 hash_ALL PRIMARY,idx2 #hash#PRIMARY 4 test.t2.i 20 Using where; Using join buffer (flat, BNLH join) -1 SIMPLE t1 hash_ALL idx2 #hash#idx2 3 test.t3.v 44 Using where; Using join buffer (incremental, BNLH join) +1 SIMPLE t1 ALL idx2 NULL NULL NULL 44 Using where; Using temporary; Using filesort +1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using where; Using index; Using join buffer (flat, BNL join) +1 SIMPLE t3 hash_ALL PRIMARY,idx2 #hash#PRIMARY 4 test.t2.i 20 Using where; Using join buffer (incremental, BNLH join) SELECT t2.v FROM t1, t2, t3 WHERE t2.v <> t3.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100 GROUP BY t2.v ORDER BY t1.pk,t2.v; @@ -4471,7 +4529,7 @@ EXPLAIN SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 -1 SIMPLE t1 ref cu cu 33 func 2 Using where; Using index +1 SIMPLE t1 ref cu cu 33 func 1 Using where; Using index SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ; i 6 @@ -4804,7 +4862,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where -1 SIMPLE t4 ref idx idx 5 test.t1.a1 2 100.00 Using where +1 SIMPLE t4 ref idx idx 5 test.t1.a1 1 100.00 Using where 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a1` AS `a1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`c2` AS `c2`,`test`.`t2`.`d2` AS `d2`,`test`.`t3`.`pk` AS `pk`,`test`.`t3`.`a3` AS `a3`,`test`.`t3`.`c3` AS `c3`,`test`.`t3`.`d3` AS `d3`,`test`.`t4`.`pk` AS `pk`,`test`.`t4`.`a4` AS `a4`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`a5` AS `a5` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`d2` = `test`.`t1`.`pk` and `test`.`t3`.`a3` = `test`.`t2`.`c2`) left join `test`.`t4` on(`test`.`t4`.`a4` = `test`.`t1`.`a1` and `test`.`t1`.`a1` is not null) left join `test`.`t5` on(`test`.`t5`.`a5` = `test`.`t3`.`a3`) where 1 @@ -4826,7 +4884,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t4 ref idx idx 5 test.t1.a1 2 100.00 Using where +1 SIMPLE t4 ref idx idx 5 test.t1.a1 1 100.00 Using where 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a1` AS `a1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`c2` AS `c2`,`test`.`t2`.`d2` AS `d2`,`test`.`t3`.`pk` AS `pk`,`test`.`t3`.`a3` AS `a3`,`test`.`t3`.`c3` AS `c3`,`test`.`t3`.`d3` AS `d3`,`test`.`t4`.`pk` AS `pk`,`test`.`t4`.`a4` AS `a4`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`a5` AS `a5` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`d2` = `test`.`t1`.`pk` and `test`.`t3`.`a3` = `test`.`t2`.`c2`) left join `test`.`t4` on(`test`.`t4`.`a4` = `test`.`t1`.`a1` and `test`.`t1`.`a1` is not null) left join `test`.`t5` on(`test`.`t5`.`a5` = `test`.`t3`.`a3`) where 1 @@ -4848,7 +4906,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where -1 SIMPLE t4 ref idx idx 5 test.t1.a1 2 100.00 Using where +1 SIMPLE t4 ref idx idx 5 test.t1.a1 1 100.00 Using where 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a1` AS `a1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`c2` AS `c2`,`test`.`t2`.`d2` AS `d2`,`test`.`t3`.`pk` AS `pk`,`test`.`t3`.`a3` AS `a3`,`test`.`t3`.`c3` AS `c3`,`test`.`t3`.`d3` AS `d3`,`test`.`t4`.`pk` AS `pk`,`test`.`t4`.`a4` AS `a4`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`a5` AS `a5` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`d2` = `test`.`t1`.`pk` and `test`.`t3`.`a3` = `test`.`t2`.`c2`) left join `test`.`t4` on(`test`.`t4`.`a4` = `test`.`t1`.`a1` and `test`.`t1`.`a1` is not null) left join `test`.`t5` on(`test`.`t5`.`a5` = `test`.`t3`.`a3`) where 1 @@ -4969,8 +5027,8 @@ FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1) LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 -1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 1 Using where -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using index +1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 1 Using where; Using index +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.a3 1 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t2.a2 1 Using where SELECT t4.a4, t5.b5 @@ -5054,6 +5112,8 @@ CREATE TABLE t2 ( f3 int(11), f2 varchar(1024), f4 varchar(10), PRIMARY KEY (f3) ); INSERT INTO t2 VALUES (6,'RPOYT','y'),(10,'JINQE','m'); +INSERT INTO t2 VALUES (100,'Q','q'),(101,'Q','q'),(102,'Q','q'),(103,'Q','q'); +INSERT INTO t2 VALUES (104,'Q','q'),(105,'Q','q'),(106,'Q','q'),(107,'Q','q'); SET SESSION join_cache_level = 1; SET SESSION optimizer_switch = 'index_condition_pushdown=off'; EXPLAIN @@ -5093,8 +5153,8 @@ SET SESSION optimizer_switch = 'index_condition_pushdown=off'; EXPLAIN SELECT * FROM t1,t2 WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0, 100) ORDER BY t1.f2 LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range f1,f2 f2 13 NULL 10 Using where -1 SIMPLE t2 ref f3 f3 67 test.t1.f2 2 Using where; Using index +1 SIMPLE t1 range f1,f2 f1 5 NULL 3 Using where; Rowid-ordered scan; Using filesort +1 SIMPLE t2 ref f3 f3 67 test.t1.f2 1 Using where; Using index SELECT * FROM t1,t2 WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1; f1 f2 f3 @@ -5103,8 +5163,8 @@ SET SESSION optimizer_switch = 'index_condition_pushdown=on'; EXPLAIN SELECT * FROM t1,t2 WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range f1,f2 f2 13 NULL 10 Using where -1 SIMPLE t2 ref f3 f3 67 test.t1.f2 2 Using where; Using index +1 SIMPLE t1 range f1,f2 f1 5 NULL 3 Using index condition; Using where; Rowid-ordered scan; Using filesort +1 SIMPLE t2 ref f3 f3 67 test.t1.f2 1 Using where; Using index SELECT * FROM t1,t2 WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1; f1 f2 f3 @@ -5205,7 +5265,7 @@ EXPLAIN SELECT a FROM t1,t2 WHERE t2.v = t1.v ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where -1 SIMPLE t2 ref idx idx 4 test.t1.v 2 +1 SIMPLE t2 ref idx idx 4 test.t1.v 1 SELECT a FROM t1,t2 WHERE t2.v = t1.v ; a 11 @@ -5263,7 +5323,7 @@ EXPLAIN SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY t2 ref c c 5 test.t1.b 2 Using index; Start temporary; End temporary +1 PRIMARY t2 ref c c 5 test.t1.b 1 Using index; Start temporary; End temporary SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2); a b 3914 17 @@ -5443,7 +5503,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t3 system NULL NULL NULL NULL 1 1 PRIMARY t2 range a,c a 5 NULL 2 Using index condition; Using where; Using filesort -1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary +1 PRIMARY t4 ref c c 5 test.t2.c 1 Using where; Start temporary; End temporary SELECT * FROM t1,t2 WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND t2.a BETWEEN 4 and 5 @@ -5461,7 +5521,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort 1 PRIMARY t3 system NULL NULL NULL NULL 1 1 PRIMARY t2 range a,c a 5 NULL 2 Using index condition; Using where -1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary +1 PRIMARY t4 ref c c 5 test.t2.c 1 Using where; Start temporary; End temporary SELECT * FROM t1,t2 WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND t2.a BETWEEN 4 and 5 @@ -5480,7 +5540,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort 1 PRIMARY t3 system NULL NULL NULL NULL 1 1 PRIMARY t2 range a,c a 5 NULL 2 Using index condition; Using where -1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary +1 PRIMARY t4 ref c c 5 test.t2.c 1 Using where; Start temporary; End temporary SELECT * FROM t1,t2 WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND t2.a BETWEEN 4 and 5 @@ -5523,7 +5583,7 @@ and t2.uid=t1.fid; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ref uid uid 5 const 4 Using where; Start temporary 1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t3.fid 1 Using index -1 PRIMARY t1 ALL uid NULL NULL NULL 11 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t1 ref uid uid 5 test.t3.fid 1 Using where; End temporary; Using join buffer (flat, BKAH join); Rowid-ordered scan 1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.fid 1 Using join buffer (flat, BKAH join); Rowid-ordered scan select name from t2, t1 where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) @@ -5975,12 +6035,12 @@ f1 f2 EXPLAIN EXTENDED SELECT * FROM temp WHERE (f1,f2) IN (SELECT t1.i1, t1.v1 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1))); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 1 100.00 -1 PRIMARY temp hash_ALL NULL #hash#$hj 9 test.t1.i1,test.t1.v1 7 100.00 Using where; Using join buffer (flat, BNLH join) +1 PRIMARY temp ALL NULL NULL NULL NULL 7 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 1 100.00 Using where 2 MATERIALIZED t2 hash_index v1 #hash#v1:v1 4:9 test.t1.v1 10 33.33 Using index; Using join buffer (flat, BNLH join) Warnings: -Note 1003 select `test`.`temp`.`f1` AS `f1`,`test`.`temp`.`f2` AS `f2` from `test`.`temp` semi join (`test`.`t2` join `test`.`t1`) where `test`.`temp`.`f1` = `test`.`t1`.`i1` and `test`.`t2`.`v1` = `test`.`t1`.`v1` and `test`.`temp`.`f2` = `test`.`t1`.`v1` +Note 1003 select `test`.`temp`.`f1` AS `f1`,`test`.`temp`.`f2` AS `f2` from `test`.`temp` semi join (`test`.`t2` join `test`.`t1`) where `test`.`t2`.`v1` = `test`.`t1`.`v1` DROP TABLE t1,t2,temp; set join_cache_level=@save_join_cache_level; # @@ -6194,6 +6254,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -6203,7 +6264,9 @@ EXPLAIN "key": "PRIMARY", "key_length": "4", "used_key_parts": ["a"], + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "a.a <= 10", "using_index": true @@ -6218,8 +6281,10 @@ EXPLAIN "key": "kp1", "key_length": "10", "used_key_parts": ["kp1", "kp2"], + "loops": 10, "rows": 836, - "filtered": 76, + "cost": "COST_REPLACED", + "filtered": 9.090909004, "index_condition": "b.kp2 <= 10", "attached_condition": "b.kp2 <= 10 and b.col1 + 1 < 33333" }, diff --git a/mysql-test/main/join_cache.test b/mysql-test/main/join_cache.test index 125ae84c309..ad2eacbe2bb 100644 --- a/mysql-test/main/join_cache.test +++ b/mysql-test/main/join_cache.test @@ -6,6 +6,7 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11; DROP DATABASE IF EXISTS world; --enable_warnings +--source include/have_innodb.inc set @org_optimizer_switch=@@optimizer_switch; set @save_join_cache_level=@@join_cache_level; @@ -53,16 +54,19 @@ set join_cache_level=1; show variables like 'join_cache_level'; +--echo # Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -72,6 +76,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -84,16 +89,19 @@ SELECT City.Name, Country.Name, CountryLanguage.Language set join_cache_level=2; show variables like 'join_cache_level'; +--echo # join_cache_level 2, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 2, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 2, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -103,6 +111,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # join_cache_level 2, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -115,16 +124,19 @@ SELECT City.Name, Country.Name, CountryLanguage.Language set join_cache_level=3; show variables like 'join_cache_level'; +--echo # join_cache_level 3, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 3, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 3, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -134,7 +146,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; - +--echo # join_cache_level 3, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -148,16 +160,19 @@ SELECT City.Name, Country.Name, CountryLanguage.Language set join_cache_level=4; show variables like 'join_cache_level'; +--echo # join_cache_level 4, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 4, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 4, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -167,6 +182,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # join_cache_level 4, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -177,11 +193,13 @@ SELECT City.Name, Country.Name, CountryLanguage.Language LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # join_cache_level 4, Query 5 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND City.Population > 5000000 WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +--echo # join_cache_level 4, Query 6 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND @@ -195,17 +213,20 @@ CREATE INDEX City_Name ON City(Name); ANALYZE TABLE City; --enable_result_log +--echo # After Analyze, Query 1 EXPLAIN SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND City.Population > 5000000 WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +--echo # After Analyze, Query 2 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND City.Population > 5000000 WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +--echo # After Analyze, Query 3 EXPLAIN SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City @@ -213,6 +234,7 @@ SELECT Country.Name, Country.Population, City.Name, City.Population (City.Population > 5000000 OR City.Name LIKE 'Za%') WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +--echo # After Analyze, Query 4 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND @@ -229,16 +251,19 @@ show variables like 'join_buffer_size'; show variables like 'join_cache_level'; +--echo # join_cache_level 1, Join_buffer_size, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 1, Join_buffer_size, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 1, Join_buffer_size, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -248,6 +273,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # join_cache_level 1, Join_buffer_size, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -260,16 +286,19 @@ SELECT City.Name, Country.Name, CountryLanguage.Language set join_cache_level=2; show variables like 'join_cache_level'; +--echo # join_cache_level 2, Join_buffer_size, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 2, Join_buffer_size, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 2, Join_buffer_size, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -279,6 +308,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # join_cache_level 2, Join_buffer_size, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -291,16 +321,19 @@ SELECT City.Name, Country.Name, CountryLanguage.Language set join_cache_level=3; show variables like 'join_cache_level'; +--echo # join_cache_level 3, Join_buffer_size, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 3, Join_buffer_size, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 3, Join_buffer_size, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -310,6 +343,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # join_cache_level 3, Join_buffer_size, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -322,16 +356,19 @@ SELECT City.Name, Country.Name, CountryLanguage.Language set join_cache_level=4; show variables like 'join_cache_level'; +--echo # join_cache_level 4, Join_buffer_size, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 4, Join_buffer_size, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # join_cache_level 4, Join_buffer_size, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -341,6 +378,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # join_cache_level 4, Join_buffer_size, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -374,16 +412,19 @@ show variables like 'join_buffer_size'; set join_cache_level=3; show variables like 'join_cache_level'; +--echo # Part 2, join_cache_level=3, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # Part 2, join_cache_level=3, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # Part 2, join_cache_level=3, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -393,6 +434,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # Part 2, join_cache_level=3, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -402,15 +444,18 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # Part 2, join_cache_level=3, Query 5 EXPLAIN SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND City.Population > 100000; +--echo # Part 2, join_cache_level=3, Query 6 SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND City.Population > 100000; +--echo # Part 2, join_cache_level=3, Query 7 #enable after fix MDEV-27871 --disable_view_protocol @@ -421,6 +466,7 @@ SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.P WHERE Country.Population > 10000000; +--echo # Part 2, join_cache_level=3, Query 8 SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) FROM Country LEFT JOIN CountryLanguage ON (CountryLanguage.Country=Country.Code AND Language='English') @@ -433,16 +479,19 @@ show variables like 'join_buffer_size'; set join_cache_level=4; show variables like 'join_cache_level'; +--echo # Part 2, join_cache_level=4, Query 1 EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # Part 2, join_cache_level=4, Query 2 --sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND Country.Name LIKE 'L%' AND City.Population > 100000; +--echo # Part 2, join_cache_level=4, Query 3 EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -452,6 +501,7 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # Part 2, join_cache_level=4, Query 4 --sorted_result SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage @@ -461,15 +511,18 @@ SELECT City.Name, Country.Name, CountryLanguage.Language CountryLanguage.Percentage > 50 AND LENGTH(Language) < LENGTH(City.Name) - 2; +--echo # Part 2, join_cache_level=4, Query 5 EXPLAIN SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND City.Population > 100000; +--echo # Part 2, join_cache_level=4, Query 6 SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND City.Population > 100000; +--echo # Part 2, join_cache_level=4, Query 7 #enable after fix MDEV-27871 --disable_view_protocol @@ -480,6 +533,7 @@ SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.P WHERE Country.Population > 10000000; +--echo # Part 2, join_cache_level=4, Query 8 SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) FROM Country LEFT JOIN CountryLanguage ON (CountryLanguage.Country=Country.Code AND Language='English') @@ -487,7 +541,7 @@ SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.P Country.Population > 10000000; --enable_view_protocol - +--echo # Part 2, join_cache_level=4, Query 9 --replace_column 9 # EXPLAIN SELECT Country.Name, Country.Population, City.Name, City.Population @@ -495,6 +549,7 @@ SELECT Country.Name, Country.Population, City.Name, City.Population ON City.Country=Country.Code AND City.Population > 5000000 WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +--echo # Part 2, join_cache_level=4, Query 10 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND City.Population > 5000000 @@ -502,6 +557,7 @@ SELECT Country.Name, Country.Population, City.Name, City.Population CREATE INDEX City_Name ON City(Name); +--echo # Part 2, join_cache_level=4, City_Name, Query 1 EXPLAIN SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City @@ -509,6 +565,7 @@ SELECT Country.Name, Country.Population, City.Name, City.Population (City.Population > 5000000 OR City.Name LIKE 'Za%') WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +--echo # Part 2, join_cache_level=4, City_Name, Query 2 SELECT Country.Name, Country.Population, City.Name, City.Population FROM Country LEFT JOIN City ON City.Country=Country.Code AND @@ -3206,6 +3263,8 @@ CREATE TABLE t2 ( f3 int(11), f2 varchar(1024), f4 varchar(10), PRIMARY KEY (f3) ); INSERT INTO t2 VALUES (6,'RPOYT','y'),(10,'JINQE','m'); +INSERT INTO t2 VALUES (100,'Q','q'),(101,'Q','q'),(102,'Q','q'),(103,'Q','q'); +INSERT INTO t2 VALUES (104,'Q','q'),(105,'Q','q'),(106,'Q','q'),(107,'Q','q'); SET SESSION join_cache_level = 1; @@ -3808,8 +3867,6 @@ drop table t0,t1,t2; --echo # of LEFT JOIN operations when using join buffer --echo # ---source include/have_innodb.inc - CREATE TABLE t1 ( id int(11) NOT NULL AUTO_INCREMENT, col1 varchar(255) NOT NULL DEFAULT '', @@ -4188,6 +4245,7 @@ analyze table t3; --echo # The following must have "B.col1 + 1 < 33333" attached to table B --echo # and not to the block-nl-join node: +--source include/explain-no-costs.inc explain format=json select * from t1 a, t3 b diff --git a/mysql-test/main/join_nested.result b/mysql-test/main/join_nested.result index fdfc5a2e7f5..7eaaf85e2bf 100644 --- a/mysql-test/main/join_nested.result +++ b/mysql-test/main/join_nested.result @@ -695,21 +695,21 @@ t0.b=t1.b AND (t9.a=1); a b a b a b a b a b a b a b a b a b a b 1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 1 -1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1 -1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 -1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1 -1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 -1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1 -1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2 -1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 2 1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 -1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 2 1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 -1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 2 1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 2 SELECT t1.a,t1.b FROM t1; @@ -855,7 +855,7 @@ ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) -1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 Using where +1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 1 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t3`.`b` and `test`.`t2`.`b` = `test`.`t3`.`b` and `test`.`t2`.`a` > 0 and `test`.`t3`.`b` is not null) where 1 @@ -969,10 +969,10 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) INSERT INTO t8 VALUES (-3,12,0), (-1,14,0), (-5,15,0), (-1,11,0), (-4,13,0); CREATE INDEX idx_b ON t8(b); EXPLAIN EXTENDED @@ -1017,12 +1017,12 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where -1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where +1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t8`.`a` >= 0 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t8`.`a` >= 0 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0); CREATE INDEX idx_b ON t1(b); CREATE INDEX idx_a ON t0(a); @@ -1062,18 +1062,18 @@ t0.b=t1.b AND (t8.b=t9.b OR t8.c IS NULL) AND (t9.a=1); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t0 ref idx_a idx_a 5 const 2 100.00 +1 SIMPLE t0 ref idx_a idx_a 5 const 2 100.00 Using where +1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 1 100.00 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t1 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where 1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where -1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where +1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2 and `test`.`t1`.`a` > 0) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2 and `test`.`t1`.`a` > 0) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b FROM t0,t1 @@ -1210,12 +1210,12 @@ EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 21 Using index 1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index -1 SIMPLE t3 ref c c 5 test.t2.b 2 Using index +1 SIMPLE t3 ref c c 5 test.t2.b 1 Using index EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 21 Using index 1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index -1 SIMPLE t3 ref c c 5 test.t2.b 2 Using index +1 SIMPLE t3 ref c c 5 test.t2.b 1 Using index SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; a b c NULL 0 0 @@ -1284,8 +1284,8 @@ NULL 2 2 DELETE FROM t3; EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 const c NULL NULL NULL 1 Impossible ON condition -1 SIMPLE t2 const b NULL NULL NULL 1 Impossible ON condition +1 SIMPLE t3 const c NULL NULL NULL 0 Impossible ON condition +1 SIMPLE t2 const b NULL NULL NULL 0 Impossible ON condition 1 SIMPLE t1 index NULL a 5 NULL 21 Using index SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; a b c @@ -1743,10 +1743,10 @@ LEFT JOIN ON t4.carrier = t1.carrier; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index package_id package_id 5 NULL 45 Using where; Using index +1 SIMPLE t3 ref package_id package_id 5 test.t2.package_id 1 Using index 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.package_id 1 1 SIMPLE t4 eq_ref PRIMARY,id PRIMARY 2 test.t1.carrier 1 Using where 1 SIMPLE t5 ref carrier_id carrier_id 5 test.t4.id 22 Using index -1 SIMPLE t3 ref package_id package_id 5 test.t2.package_id 1 Using index SELECT COUNT(*) FROM ((t2 JOIN t1 ON t2.package_id = t1.id) JOIN t3 ON t3.package_id = t1.id) diff --git a/mysql-test/main/join_nested.test b/mysql-test/main/join_nested.test index ed1fe4c9f7e..ee89c91e734 100644 --- a/mysql-test/main/join_nested.test +++ b/mysql-test/main/join_nested.test @@ -364,6 +364,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, SELECT t9.a,t9.b FROM t9; +--sorted_result SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b FROM t0,t1 diff --git a/mysql-test/main/join_nested_jcl6.result b/mysql-test/main/join_nested_jcl6.result index 451accd7b1c..2148fb859b4 100644 --- a/mysql-test/main/join_nested_jcl6.result +++ b/mysql-test/main/join_nested_jcl6.result @@ -703,23 +703,23 @@ t0.b=t1.b AND (t8.b=t9.b OR t8.c IS NULL) AND (t9.a=1); a b a b a b a b a b a b a b a b a b a b -1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1 -1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1 +1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 1 +1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2 1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 1 2 -1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1 1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 2 -1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 2 1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 -1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 +1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 -1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1 1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1 1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 2 1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 1 1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 2 -1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 1 -1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2 SELECT t1.a,t1.b FROM t1; a b @@ -864,7 +864,7 @@ ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) -1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 1 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) Warnings: Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t3`.`b` and `test`.`t2`.`b` = `test`.`t3`.`b` and `test`.`t2`.`a` > 0 and `test`.`t3`.`b` is not null) where 1 @@ -978,10 +978,10 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) INSERT INTO t8 VALUES (-3,12,0), (-1,14,0), (-5,15,0), (-1,11,0), (-4,13,0); CREATE INDEX idx_b ON t8(b); EXPLAIN EXTENDED @@ -1026,12 +1026,12 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t8`.`a` >= 0 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t8`.`a` >= 0 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0); CREATE INDEX idx_b ON t1(b); CREATE INDEX idx_a ON t0(a); @@ -1071,18 +1071,18 @@ t0.b=t1.b AND (t8.b=t9.b OR t8.c IS NULL) AND (t9.a=1); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t0 ref idx_a idx_a 5 const 2 100.00 -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t1 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t0 ref idx_a idx_a 5 const 2 100.00 Using where +1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan Warnings: -Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2 and `test`.`t1`.`a` > 0) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2 and `test`.`t1`.`a` > 0) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b FROM t0,t1 @@ -1219,12 +1219,12 @@ EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 21 Using index 1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index -1 SIMPLE t3 ref c c 5 test.t2.b 2 Using index +1 SIMPLE t3 ref c c 5 test.t2.b 1 Using index EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 21 Using index 1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index -1 SIMPLE t3 ref c c 5 test.t2.b 2 Using index +1 SIMPLE t3 ref c c 5 test.t2.b 1 Using index SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; a b c NULL 0 0 @@ -1293,8 +1293,8 @@ NULL 2 2 DELETE FROM t3; EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 const c NULL NULL NULL 1 Impossible ON condition -1 SIMPLE t2 const b NULL NULL NULL 1 Impossible ON condition +1 SIMPLE t3 const c NULL NULL NULL 0 Impossible ON condition +1 SIMPLE t2 const b NULL NULL NULL 0 Impossible ON condition 1 SIMPLE t1 index NULL a 5 NULL 21 Using index SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; a b c @@ -1752,10 +1752,10 @@ LEFT JOIN ON t4.carrier = t1.carrier; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index package_id package_id 5 NULL 45 Using where; Using index +1 SIMPLE t3 ref package_id package_id 5 test.t2.package_id 1 Using index 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.package_id 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t4 eq_ref PRIMARY,id PRIMARY 2 test.t1.carrier 1 Using where 1 SIMPLE t5 ref carrier_id carrier_id 5 test.t4.id 22 Using index -1 SIMPLE t3 ref package_id package_id 5 test.t2.package_id 1 Using index SELECT COUNT(*) FROM ((t2 JOIN t1 ON t2.package_id = t1.id) JOIN t3 ON t3.package_id = t1.id) @@ -2085,9 +2085,9 @@ ON t6.b >= 2 AND t5.b=t7.b AND (t8.a > 0 OR t8.c IS NULL) AND t6.a>0 AND t7.a>0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t5 ALL NULL NULL NULL NULL 3 -1 SIMPLE t7 range PRIMARY,b_i PRIMARY 4 NULL 2 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) +1 SIMPLE t7 ref|filter PRIMARY,b_i b_i|PRIMARY 5|4 test.t5.b 1 (29%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter 1 SIMPLE t6 range|filter PRIMARY,b_i PRIMARY|b_i 4|5 NULL 3 (86%) Using where; Rowid-ordered scan; Using join buffer (incremental, BNL join); Using rowid filter -1 SIMPLE t8 ref b_i b_i 5 test.t5.b 2 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t8 ref b_i b_i 5 test.t5.b 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM t5 LEFT JOIN @@ -2120,9 +2120,9 @@ FROM t5 LEFT JOIN ON (t5.b=t8.b); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 -1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t8 ref b_i b_i 5 test.t5.b 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM t5 LEFT JOIN (t6 LEFT JOIN t7 ON t7.a=1, t8) @@ -2137,9 +2137,9 @@ FROM t5 LEFT JOIN ON (t5.b=t8.b); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 -1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t7 ref b_i b_i 5 const 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan -1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t8 ref b_i b_i 5 test.t5.b 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM t5 LEFT JOIN (t6 LEFT JOIN t7 ON t7.b=2, t8) @@ -2154,7 +2154,7 @@ FROM t5 LEFT JOIN ON (t5.b=t8.b); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 -1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t8 ref b_i b_i 5 test.t5.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join) 1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b diff --git a/mysql-test/main/join_outer.result b/mysql-test/main/join_outer.result index d6ab8c7dc9c..ce9dbfb8c3d 100644 --- a/mysql-test/main/join_outer.result +++ b/mysql-test/main/join_outer.result @@ -1230,7 +1230,7 @@ EXPLAIN SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref idx idx 4 test.t1.id 2 Using where; Not exists +1 SIMPLE t2 ref idx idx 4 test.t1.id 1 Using where; Not exists flush status; SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL; id a @@ -1430,7 +1430,7 @@ WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 -1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index; Using filesort +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; @@ -1852,7 +1852,7 @@ WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 -1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index; Using filesort +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; @@ -2080,7 +2080,7 @@ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 ORDER BY t1.b; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ref idx idx 4 const 2 100.00 Using where -1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 +1 SIMPLE t2 ref c c 5 test.t1.a 1 100.00 Warnings: Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t1`.`b` = 5 order by `test`.`t1`.`b` SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a @@ -2097,7 +2097,7 @@ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 ORDER BY t1.b; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ref PRIMARY,idx idx 4 const 2 100.00 Using where -1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 +1 SIMPLE t2 ref c c 5 test.t1.a 1 100.00 Warnings: Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t1`.`b` = 5 order by `test`.`t1`.`b` SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a @@ -2260,7 +2260,7 @@ create table t2 (a int, b int, c int, key(b), key(c)); insert into t2 select @a:=A.a + 10*B.a+100*C.a, IF(@a<900, NULL, @a), -IF(@a<500, NULL, @a) +IF(@a<400, NULL, @a) from t1 A, t1 B, t1 C; delete from t1 where a=0; # Check that there are different #rows of NULLs for b and c, both !=10: @@ -2269,7 +2269,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref b b 5 const 780 Using index condition explain select * from t2 force index (c) where c is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref c c 5 const 393 Using index condition +1 SIMPLE t2 ref c c 5 const 282 Using index condition explain select * from t1 left join t2 on t2.b is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 diff --git a/mysql-test/main/join_outer.test b/mysql-test/main/join_outer.test index 5e1e83e4049..8e4c343f247 100644 --- a/mysql-test/main/join_outer.test +++ b/mysql-test/main/join_outer.test @@ -1813,7 +1813,7 @@ create table t2 (a int, b int, c int, key(b), key(c)); insert into t2 select @a:=A.a + 10*B.a+100*C.a, IF(@a<900, NULL, @a), - IF(@a<500, NULL, @a) + IF(@a<400, NULL, @a) from t1 A, t1 B, t1 C; delete from t1 where a=0; diff --git a/mysql-test/main/join_outer_innodb.result b/mysql-test/main/join_outer_innodb.result index 809a980576d..dbbbe89944b 100644 --- a/mysql-test/main/join_outer_innodb.result +++ b/mysql-test/main/join_outer_innodb.result @@ -435,47 +435,47 @@ left join t16 on t15.o1 = t16.p1 where t1.a10 = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL a4,a6,a5,a7 NULL NULL NULL 3 Using where -1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a1 1 Using index -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.b2 1 Using where; Using index -1 SIMPLE t8 eq_ref PRIMARY PRIMARY 1 test.t1.a4 1 Using index -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.a2 1 Using index +1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a1 1 +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.b2 1 Using where +1 SIMPLE t10 eq_ref PRIMARY PRIMARY 1 test.t1.a6 1 +1 SIMPLE t8 eq_ref PRIMARY PRIMARY 1 test.t1.a4 1 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.a2 1 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.d1 1 Using where -1 SIMPLE t6 eq_ref PRIMARY PRIMARY 4 test.t1.a3 1 Using where; Using index +1 SIMPLE t6 eq_ref PRIMARY PRIMARY 4 test.t1.a3 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 1 test.t1.a7 1 1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t1.a5 1 1 SIMPLE t12 eq_ref PRIMARY PRIMARY 4 test.t11.k3 1 Using where 1 SIMPLE l2 eq_ref PRIMARY PRIMARY 4 test.t11.k4 1 Using where 1 SIMPLE t9 ref PRIMARY PRIMARY 1 test.t1.a4 1 -1 SIMPLE t13 ref PRIMARY,m3 m3 8 const,test.t1.a1 1 Using index -1 SIMPLE l4 eq_ref PRIMARY PRIMARY 4 test.t13.m2 1 Using where; Using index -1 SIMPLE m2 ref PRIMARY,m3 m3 8 const,test.t1.a1 1 Using index +1 SIMPLE t13 ref PRIMARY,m3 m3 8 const,test.t1.a1 3 Using index +1 SIMPLE l4 eq_ref PRIMARY PRIMARY 4 test.t13.m2 1 Using where +1 SIMPLE m2 ref PRIMARY,m3 m3 8 const,test.t1.a1 3 Using index 1 SIMPLE l3 eq_ref PRIMARY PRIMARY 4 test.m2.m2 1 Using where 1 SIMPLE t14 eq_ref PRIMARY PRIMARY 2 test.t1.a8 1 Using where -1 SIMPLE t15 eq_ref PRIMARY PRIMARY 2 test.t1.a9 1 Using where; Using index +1 SIMPLE t15 eq_ref PRIMARY PRIMARY 2 test.t1.a9 1 Using where 1 SIMPLE t16 ref PRIMARY PRIMARY 2 test.t15.o1 1 Using where -1 SIMPLE t10 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL a4,a6,a5,a7 NULL NULL NULL 3 Using where -1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a1 1 Using index -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.b2 1 Using where; Using index -1 SIMPLE t8 eq_ref PRIMARY PRIMARY 1 test.t1.a4 1 Using index -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.a2 1 Using index +1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a1 1 +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.b2 1 Using where +1 SIMPLE t10 eq_ref PRIMARY PRIMARY 1 test.t1.a6 1 +1 SIMPLE t8 eq_ref PRIMARY PRIMARY 1 test.t1.a4 1 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.a2 1 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t4.d1 1 Using where -1 SIMPLE t6 eq_ref PRIMARY PRIMARY 4 test.t1.a3 1 Using where; Using index +1 SIMPLE t6 eq_ref PRIMARY PRIMARY 4 test.t1.a3 1 Using where 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 1 test.t1.a7 1 1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t1.a5 1 1 SIMPLE t12 eq_ref PRIMARY PRIMARY 4 test.t11.k3 1 Using where 1 SIMPLE l2 eq_ref PRIMARY PRIMARY 4 test.t11.k4 1 Using where 1 SIMPLE t9 ref PRIMARY PRIMARY 1 test.t1.a4 1 -1 SIMPLE t13 ref PRIMARY,m3 m3 8 const,test.t1.a1 1 Using index -1 SIMPLE l4 eq_ref PRIMARY PRIMARY 4 test.t13.m2 1 Using where; Using index -1 SIMPLE m2 ref PRIMARY,m3 m3 8 const,test.t1.a1 1 Using index +1 SIMPLE t13 ref PRIMARY,m3 m3 8 const,test.t1.a1 3 Using index +1 SIMPLE l4 eq_ref PRIMARY PRIMARY 4 test.t13.m2 1 Using where +1 SIMPLE m2 ref PRIMARY,m3 m3 8 const,test.t1.a1 3 Using index 1 SIMPLE l3 eq_ref PRIMARY PRIMARY 4 test.m2.m2 1 Using where 1 SIMPLE t14 eq_ref PRIMARY PRIMARY 2 test.t1.a8 1 Using where -1 SIMPLE t15 eq_ref PRIMARY PRIMARY 2 test.t1.a9 1 Using where; Using index +1 SIMPLE t15 eq_ref PRIMARY PRIMARY 2 test.t1.a9 1 Using where 1 SIMPLE t16 ref PRIMARY PRIMARY 2 test.t15.o1 1 Using where -1 SIMPLE t10 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) drop view v1; drop table t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16; # diff --git a/mysql-test/main/join_outer_jcl6.result b/mysql-test/main/join_outer_jcl6.result index 8dcc41638bb..ff5e76b78ad 100644 --- a/mysql-test/main/join_outer_jcl6.result +++ b/mysql-test/main/join_outer_jcl6.result @@ -1237,7 +1237,7 @@ EXPLAIN SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref idx idx 4 test.t1.id 2 Using where; Not exists; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref idx idx 4 test.t1.id 1 Using where; Not exists; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan flush status; SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL; id a @@ -1437,7 +1437,7 @@ WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 -1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index; Using filesort +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; @@ -1859,7 +1859,7 @@ WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 -1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index; Using filesort +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL GROUP BY t2.f1, t2.f2; @@ -2087,7 +2087,7 @@ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 ORDER BY t1.b; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ref idx idx 4 const 2 100.00 Using where -1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref c c 5 test.t1.a 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t1`.`b` = 5 order by `test`.`t1`.`b` SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a @@ -2104,7 +2104,7 @@ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 ORDER BY t1.b; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ref PRIMARY,idx idx 4 const 2 100.00 Using where -1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 ref c c 5 test.t1.a 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t1`.`b` = 5 order by `test`.`t1`.`b` SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a @@ -2267,7 +2267,7 @@ create table t2 (a int, b int, c int, key(b), key(c)); insert into t2 select @a:=A.a + 10*B.a+100*C.a, IF(@a<900, NULL, @a), -IF(@a<500, NULL, @a) +IF(@a<400, NULL, @a) from t1 A, t1 B, t1 C; delete from t1 where a=0; # Check that there are different #rows of NULLs for b and c, both !=10: @@ -2276,7 +2276,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref b b 5 const 780 Using index condition explain select * from t2 force index (c) where c is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref c c 5 const 393 Using index condition +1 SIMPLE t2 ref c c 5 const 282 Using index condition explain select * from t1 left join t2 on t2.b is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 diff --git a/mysql-test/main/key.result b/mysql-test/main/key.result index 2e2c8d894f0..e6bb46af2b1 100644 --- a/mysql-test/main/key.result +++ b/mysql-test/main/key.result @@ -231,11 +231,14 @@ numeropost 1 EXPLAIN SELECT numeropost FROM t1 WHERE numreponse='1'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 const numreponse numreponse 4 const 1 Using index +1 SIMPLE t1 const numreponse numreponse 4 const 1 FLUSH TABLES; SELECT numeropost FROM t1 WHERE numreponse='1'; numeropost 1 +EXPLAIN SELECT numreponse+0 FROM t1 WHERE numreponse='1'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const numreponse numreponse 4 const 1 Using index drop table t1; create table t1 (c varchar(30) character set utf8, t text character set utf8, unique (c(2)), unique (t(3))) engine=myisam; show create table t1; @@ -610,7 +613,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t1 range a a 5 NULL 5 Using where; Using index +2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index for group-by SELECT 1 as RES FROM t1 AS t1_outer WHERE (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12; RES @@ -628,19 +631,19 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort SHOW STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 9.212184 +Last_query_cost 0.014784 EXPLAIN SELECT a, SUM( b ) FROM t1 USE INDEX( a ) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort SHOW STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 9.212184 +Last_query_cost 0.014784 EXPLAIN SELECT a, SUM( b ) FROM t1 FORCE INDEX( a ) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 5 NULL 6 SHOW STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 14.199000 +Last_query_cost 0.014784 DROP TABLE t1; # # MDEV-21480: Unique key using ref access though eq_ref access can be used @@ -689,3 +692,42 @@ drop table t1,t2; # create table t1 (a int, b int, key(a), key(a desc)); drop table t1; +# Check some issues with FORCE INDEX and full index scans +# (Does FORCE INDEX force an index scan) +# +create table t1 (a int primary key, b int, c int, d int, +key k1 (b) using BTREE, key k2 (c,d) using btree) engine=heap; +insert into t1 select seq as a, seq as b, seq as c, seq as d +from seq_1_to_100; +explain select sum(a+b) from t1 force index (k1) where b>0 and a=99; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range k1 k1 5 NULL 100 Using where +explain select sum(a+b) from t1 force index (k1) where a>0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 100 Using where +explain select sum(a+b) from t1 force index (k1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 100 +explain select sum(a+b) from t1 force index for join (k1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 100 +explain select sum(a+b) from t1 force index for order by (k1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 100 +explain select sum(a+b) from t1 force index (k1,k2); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 100 +select sum(a+b) from t1 force index (k1); +sum(a+b) +10100 +explain select sum(a+b) from t1 force index (primary); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 100 +select sum(a+b) from t1 force index (primary); +sum(a+b) +10100 +explain select straight_join sum(a+b) from seq_1_to_10 as s, t1 force index (k2) where t1.a=s.seq; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE s index PRIMARY PRIMARY 8 NULL 10 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) +drop table t1; diff --git a/mysql-test/main/key.test b/mysql-test/main/key.test index 29e08b8834a..7ec18ad5d0a 100644 --- a/mysql-test/main/key.test +++ b/mysql-test/main/key.test @@ -227,9 +227,12 @@ drop table t1; CREATE TABLE t1 (numeropost mediumint(8) unsigned NOT NULL default '0', numreponse int(10) unsigned NOT NULL auto_increment, PRIMARY KEY (numeropost,numreponse), UNIQUE KEY numreponse (numreponse)); INSERT INTO t1 (numeropost,numreponse) VALUES ('1','1'),('1','2'),('2','3'),('2','4'); SELECT numeropost FROM t1 WHERE numreponse='1'; +# No 'Using index' EXPLAIN SELECT numeropost FROM t1 WHERE numreponse='1'; FLUSH TABLES; SELECT numeropost FROM t1 WHERE numreponse='1'; +# This one will have 'Using index' +EXPLAIN SELECT numreponse+0 FROM t1 WHERE numreponse='1'; drop table t1; # @@ -608,3 +611,23 @@ drop table t1,t2; --echo # create table t1 (a int, b int, key(a), key(a desc)); drop table t1; + +--echo # Check some issues with FORCE INDEX and full index scans +--echo # (Does FORCE INDEX force an index scan) +--echo # + +create table t1 (a int primary key, b int, c int, d int, +key k1 (b) using BTREE, key k2 (c,d) using btree) engine=heap; +insert into t1 select seq as a, seq as b, seq as c, seq as d +from seq_1_to_100; +explain select sum(a+b) from t1 force index (k1) where b>0 and a=99; +explain select sum(a+b) from t1 force index (k1) where a>0; +explain select sum(a+b) from t1 force index (k1); +explain select sum(a+b) from t1 force index for join (k1); +explain select sum(a+b) from t1 force index for order by (k1); +explain select sum(a+b) from t1 force index (k1,k2); +select sum(a+b) from t1 force index (k1); +explain select sum(a+b) from t1 force index (primary); +select sum(a+b) from t1 force index (primary); +explain select straight_join sum(a+b) from seq_1_to_10 as s, t1 force index (k2) where t1.a=s.seq; +drop table t1; diff --git a/mysql-test/main/key_cache.result b/mysql-test/main/key_cache.result index 4a5df2da65d..0ac03750081 100644 --- a/mysql-test/main/key_cache.result +++ b/mysql-test/main/key_cache.result @@ -134,7 +134,7 @@ i explain select count(*) from t1, t2 where t1.p = t2.i; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using index -1 SIMPLE t2 ref k1 k1 5 test.t1.p 2 Using index +1 SIMPLE t2 ref k1 k1 5 test.t1.p 1 Using index select count(*) from t1, t2 where t1.p = t2.i; count(*) 3 @@ -434,31 +434,31 @@ p i a 3 1 yyyy 4 3 zzzz update t1 set p=3 where p=1; -update t2 set i=2 where i=1; +set statement optimizer_scan_setup_cost=0 for update t2 set i=2 where i=1; select * from information_schema.session_status where variable_name like 'key_%' and variable_name != 'Key_blocks_unused'; VARIABLE_NAME VARIABLE_VALUE KEY_BLOCKS_NOT_FLUSHED 0 KEY_BLOCKS_USED 4 KEY_BLOCKS_WARM 0 -KEY_READ_REQUESTS 22 +KEY_READ_REQUESTS 21 KEY_READS 0 KEY_WRITE_REQUESTS 26 KEY_WRITES 6 select variable_value into @key_blocks_unused from information_schema.session_status where variable_name = 'Key_blocks_unused'; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default NULL NULL 2097152 1024 4 # 0 22 0 26 6 +default NULL NULL 2097152 1024 4 # 0 21 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 delete from t2 where a='zzzz'; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default NULL NULL 2097152 1024 4 # 0 29 0 32 9 +default NULL NULL 2097152 1024 4 # 0 28 0 32 9 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 delete from t1; delete from t2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default NULL NULL 2097152 1024 4 # 0 29 0 32 9 +default NULL NULL 2097152 1024 4 # 0 28 0 32 9 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 set global key_cache_segments=2; select @@key_cache_segments; @@ -482,13 +482,13 @@ p i a 3 1 yyyy 4 3 zzzz update t1 set p=3 where p=1; -update t2 set i=2 where i=1; +set statement optimizer_scan_setup_cost=0 for update t2 set i=2 where i=1; select * from information_schema.session_status where variable_name like 'key_%' and variable_name != 'Key_blocks_unused'; VARIABLE_NAME VARIABLE_VALUE KEY_BLOCKS_NOT_FLUSHED 0 KEY_BLOCKS_USED 4 KEY_BLOCKS_WARM 0 -KEY_READ_REQUESTS 22 +KEY_READ_REQUESTS 21 KEY_READS 0 KEY_WRITE_REQUESTS 26 KEY_WRITES 6 @@ -497,13 +497,13 @@ variable_value < @key_blocks_unused 1 select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 2097152 1024 4 # 0 22 0 26 6 +default 2 NULL 2097152 1024 4 # 0 21 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 delete from t1; delete from t2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 2097152 1024 4 # 0 22 0 26 6 +default 2 NULL 2097152 1024 4 # 0 21 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 set global key_cache_segments=1; select @@key_cache_segments; @@ -527,13 +527,13 @@ p i a 3 1 yyyy 4 3 zzzz update t1 set p=3 where p=1; -update t2 set i=2 where i=1; +set statement optimizer_scan_setup_cost=0 for update t2 set i=2 where i=1; select * from information_schema.session_status where variable_name like 'key_%' and variable_name != 'Key_blocks_unused'; VARIABLE_NAME VARIABLE_VALUE KEY_BLOCKS_NOT_FLUSHED 0 KEY_BLOCKS_USED 4 KEY_BLOCKS_WARM 0 -KEY_READ_REQUESTS 22 +KEY_READ_REQUESTS 21 KEY_READS 0 KEY_WRITE_REQUESTS 26 KEY_WRITES 6 @@ -542,13 +542,13 @@ variable_value = @key_blocks_unused 1 select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 1 NULL 2097152 1024 4 # 0 22 0 26 6 +default 1 NULL 2097152 1024 4 # 0 21 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 delete from t1; delete from t2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 1 NULL 2097152 1024 4 # 0 22 0 26 6 +default 1 NULL 2097152 1024 4 # 0 21 0 26 6 small NULL NULL 1048576 1024 1 # 0 1 0 2 1 flush tables; flush status; @@ -583,10 +583,10 @@ p i a 3 1 yyyy 4 3 zzzz update t1 set p=3 where p=1; -update t2 set i=2 where i=1; +set statement optimizer_scan_setup_cost=0 for update t2 set i=2 where i=1; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 4 # 0 22 0 26 6 +default 2 NULL 32768 1024 4 # 0 21 0 26 6 small NULL NULL 1048576 1024 1 # 0 0 0 0 0 insert into t1(a) select a from t1; insert into t1(a) select a from t1; @@ -606,7 +606,7 @@ insert into t2(i,a) select i,a from t2; insert into t2(i,a) select i,a from t2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 6733 # 3684 103 +default 2 NULL 32768 1024 # # 0 6732 # 3684 103 small NULL NULL 1048576 1024 # # 0 0 # 0 0 select * from t1 where p between 1010 and 1020 ; p a @@ -625,12 +625,16 @@ p i a 1020 3 zzzz select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES -default 2 NULL 32768 1024 # # 0 6750 # 3684 103 +default 2 NULL 32768 1024 # # 0 6749 # 3684 103 small NULL NULL 1048576 1024 # # 0 0 # 0 0 +analyze table t2; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK flush tables; flush status; update t1 set a='zzzz' where a='qqqq'; -update t2 set i=1 where i=2; +set statement optimizer_scan_setup_cost=0 for update t2 set i=1 where i=2; select * from information_schema.key_caches where segment_number is null; KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES default 2 NULL 32768 1024 # # 0 3076 18 1552 18 diff --git a/mysql-test/main/key_cache.test b/mysql-test/main/key_cache.test index 9bd57f017f0..baca5c07fec 100644 --- a/mysql-test/main/key_cache.test +++ b/mysql-test/main/key_cache.test @@ -299,7 +299,7 @@ insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), select * from t1; select * from t2; update t1 set p=3 where p=1; -update t2 set i=2 where i=1; +set statement optimizer_scan_setup_cost=0 for update t2 set i=2 where i=1; select * from information_schema.session_status where variable_name like 'key_%' and variable_name != 'Key_blocks_unused'; select variable_value into @key_blocks_unused from information_schema.session_status where variable_name = 'Key_blocks_unused'; @@ -331,8 +331,7 @@ insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), select * from t1; select * from t2; update t1 set p=3 where p=1; -update t2 set i=2 where i=1; - +set statement optimizer_scan_setup_cost=0 for update t2 set i=2 where i=1; select * from information_schema.session_status where variable_name like 'key_%' and variable_name != 'Key_blocks_unused'; select variable_value < @key_blocks_unused from information_schema.session_status where variable_name = 'Key_blocks_unused'; @@ -357,7 +356,7 @@ insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), select * from t1; select * from t2; update t1 set p=3 where p=1; -update t2 set i=2 where i=1; +set statement optimizer_scan_setup_cost=0 for update t2 set i=2 where i=1; select * from information_schema.session_status where variable_name like 'key_%' and variable_name != 'Key_blocks_unused'; select variable_value = @key_blocks_unused from information_schema.session_status where variable_name = 'Key_blocks_unused'; @@ -389,7 +388,7 @@ insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'), select * from t1; select * from t2; update t1 set p=3 where p=1; -update t2 set i=2 where i=1; +set statement optimizer_scan_setup_cost=0 for update t2 set i=2 where i=1; --replace_column 7 # select * from information_schema.key_caches where segment_number is null; @@ -422,9 +421,10 @@ select * from t2 where p between 1010 and 1020 ; --replace_column 6 # 7 # 10 # select * from information_schema.key_caches where segment_number is null; +analyze table t2; flush tables; flush status; update t1 set a='zzzz' where a='qqqq'; -update t2 set i=1 where i=2; +set statement optimizer_scan_setup_cost=0 for update t2 set i=1 where i=2; --replace_column 6 # 7 # select * from information_schema.key_caches where segment_number is null; diff --git a/mysql-test/main/key_diff.result b/mysql-test/main/key_diff.result index af928fcb203..f419be55208 100644 --- a/mysql-test/main/key_diff.result +++ b/mysql-test/main/key_diff.result @@ -36,7 +36,7 @@ a a a a explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL a NULL NULL NULL 5 -1 SIMPLE t2 ALL b NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ref b b 4 test.t1.a 1 Using index condition select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a; a b a b A B a a diff --git a/mysql-test/main/limit_rows_examined.result b/mysql-test/main/limit_rows_examined.result index f0a22b8f3f2..9d3d5bbf0ab 100644 --- a/mysql-test/main/limit_rows_examined.result +++ b/mysql-test/main/limit_rows_examined.result @@ -211,45 +211,42 @@ explain select * from t1 where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 11); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 2 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) select * from t1 where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 11); c1 bb -Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 12 rows, which exceeds LIMIT ROWS EXAMINED (11). The query result may be incomplete +cc +dd explain select * from t1 where c1 IN (select * from t2 where c2 > ' ') LIMIT ROWS EXAMINED 11; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 2 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) select * from t1 where c1 IN (select * from t2 where c2 > ' ') LIMIT ROWS EXAMINED 11; c1 bb -Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 12 rows, which exceeds LIMIT ROWS EXAMINED (11). The query result may be incomplete +cc +dd explain select * from t1 where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0) LIMIT ROWS EXAMINED 11; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 2 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) select * from t1 where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0) LIMIT ROWS EXAMINED 11; c1 bb -Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 12 rows, which exceeds LIMIT ROWS EXAMINED (11). The query result may be incomplete +cc +dd explain select * from t1i where c1 IN (select * from t2i where c2 > ' ') @@ -416,24 +413,22 @@ c1 bb cc dd -select * from v1 LIMIT ROWS EXAMINED 17; +select * from v1 LIMIT ROWS EXAMINED 10; +c1 +bb +cc +dd +select * from v1 LIMIT ROWS EXAMINED 8; c1 bb cc dd Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 18 rows, which exceeds LIMIT ROWS EXAMINED (17). The query result may be incomplete -select * from v1 LIMIT ROWS EXAMINED 16; +Warning 1931 Query execution was interrupted. The query examined at least 9 rows, which exceeds LIMIT ROWS EXAMINED (8). The query result may be incomplete +select * from v1 LIMIT ROWS EXAMINED 3; c1 -bb -cc Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 17 rows, which exceeds LIMIT ROWS EXAMINED (16). The query result may be incomplete -select * from v1 LIMIT ROWS EXAMINED 11; -c1 -bb -Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 12 rows, which exceeds LIMIT ROWS EXAMINED (11). The query result may be incomplete +Warning 1931 Query execution was interrupted. The query examined at least 4 rows, which exceeds LIMIT ROWS EXAMINED (3). The query result may be incomplete drop view v1; explain select * @@ -441,17 +436,16 @@ from (select * from t1 where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0)) as tmp LIMIT ROWS EXAMINED 11; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 2 func 1 -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) select * from (select * from t1 where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0)) as tmp LIMIT ROWS EXAMINED 11; c1 bb -Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 12 rows, which exceeds LIMIT ROWS EXAMINED (11). The query result may be incomplete +cc +dd ========================================================================= Aggregation ========================================================================= diff --git a/mysql-test/main/limit_rows_examined.test b/mysql-test/main/limit_rows_examined.test index 2315580410f..512058e1eb6 100644 --- a/mysql-test/main/limit_rows_examined.test +++ b/mysql-test/main/limit_rows_examined.test @@ -277,9 +277,9 @@ create view v1 as select * from t1 where c1 IN (select * from t2 where c2 > ' '); select * from v1; -select * from v1 LIMIT ROWS EXAMINED 17; -select * from v1 LIMIT ROWS EXAMINED 16; -select * from v1 LIMIT ROWS EXAMINED 11; +select * from v1 LIMIT ROWS EXAMINED 10; +select * from v1 LIMIT ROWS EXAMINED 8; +select * from v1 LIMIT ROWS EXAMINED 3; drop view v1; diff --git a/mysql-test/main/lock_sync.result b/mysql-test/main/lock_sync.result index 2d7a175e420..af3fbe8a784 100644 --- a/mysql-test/main/lock_sync.result +++ b/mysql-test/main/lock_sync.result @@ -67,8 +67,6 @@ declare j int; select i from t1 where i = 1 into j; return j; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f2() returns int begin declare k int; @@ -76,8 +74,6 @@ select i from t1 where i = 1 into k; insert into t2 values (k + 5); return 0; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f3() returns int begin return (select i from t1 where i = 3); @@ -101,16 +97,12 @@ declare k int; select i from v1 where i = 1 into k; return k; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f7() returns int begin declare k int; select j from v2 where j = 1 into k; return k; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f8() returns int begin declare k int; @@ -118,8 +110,6 @@ select i from v1 where i = 1 into k; insert into t2 values (k+5); return k; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f9() returns int begin update v2 set j=j+10 where j=1; @@ -149,8 +139,6 @@ create procedure p2(inout p int) begin select i from t1 where i = 1 into p; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function f14() returns int begin declare k int; @@ -178,8 +166,6 @@ select i from t1 where i = 1 into j; call p3; return 1; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create procedure p3() begin create temporary table if not exists temp1 (a int); @@ -192,8 +178,6 @@ declare k int; select i from t1 where i=1 into k; set new.l= k+1; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create trigger t4_bu before update on t4 for each row begin if (select i from t1 where i=1) then diff --git a/mysql-test/main/locking_clause.result b/mysql-test/main/locking_clause.result index d2ebfe4799f..8cfdfb91037 100644 --- a/mysql-test/main/locking_clause.result +++ b/mysql-test/main/locking_clause.result @@ -149,16 +149,8 @@ DROP USER test2@localhost; # MYSQL 8 # SELECT 1 FROM DUAL LIMIT 1 INTO @var FOR UPDATE; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT 1 FROM DUAL LIMIT 1 FOR UPDATE INTO @var; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT 1 FROM DUAL LIMIT 1 INTO @var FOR UPDATE INTO @var; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INTO @var' at line 1 SELECT 1 UNION SELECT 1 FOR UPDATE INTO @var; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT 1 UNION SELECT 1 INTO @var FOR UPDATE; -Warnings: -Warning 1287 ' INTO FROM...' instead diff --git a/mysql-test/main/long_unique.result b/mysql-test/main/long_unique.result index 7f8110a283e..664c9e82ec6 100644 --- a/mysql-test/main/long_unique.result +++ b/mysql-test/main/long_unique.result @@ -1195,20 +1195,20 @@ ERROR 42S22: Unknown column 'DB_ROW_HASH_1' in 'IN/ALL/ANY subquery' select DB_ROW_HASH_1, DB_ROW_HASH_2 from t1,t2 where DB_ROW_HASH_1 in (select DB_ROW_HASH_1 from t2); DB_ROW_HASH_1 DB_ROW_HASH_2 11 1 -22 2 -33 3 -44 4 +11 1 +11 1 11 1 22 2 -33 3 -44 4 -11 1 +22 2 +22 2 22 2 33 3 -44 4 -11 1 -22 2 33 3 +33 3 +33 3 +44 4 +44 4 +44 4 44 4 select * from t2 where DB_ROW_HASH_1 in (select DB_ROW_HASH_1 from t1); DB_ROW_HASH_1 DB_ROW_HASH_2 diff --git a/mysql-test/main/long_unique.test b/mysql-test/main/long_unique.test index fa49b6a5ad4..3203675a7ad 100644 --- a/mysql-test/main/long_unique.test +++ b/mysql-test/main/long_unique.test @@ -389,6 +389,7 @@ select DB_ROW_HASH_1, DB_ROW_HASH_2 from t1; select DB_ROW_HASH_1, DB_ROW_HASH_2 from t1,t2; --error ER_BAD_FIELD_ERROR select * from t1 where DB_ROW_HASH_1 in (select DB_ROW_HASH_1 from t2); +--sorted_result select DB_ROW_HASH_1, DB_ROW_HASH_2 from t1,t2 where DB_ROW_HASH_1 in (select DB_ROW_HASH_1 from t2); select * from t2 where DB_ROW_HASH_1 in (select DB_ROW_HASH_1 from t1); --error ER_BAD_FIELD_ERROR diff --git a/mysql-test/main/mdev-25830.result b/mysql-test/main/mdev-25830.result index e62d1ff3f55..6de3e5836d3 100644 --- a/mysql-test/main/mdev-25830.result +++ b/mysql-test/main/mdev-25830.result @@ -25,8 +25,8 @@ ORDER BY sysapproval_approver0.`order` LIMIT 0, 50 ; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE task2 range PRIMARY,sys_class_name_2,sys_domain_path PRIMARY 96 NULL 1 0.00 100.00 100.00 Using where; Using temporary; Using filesort -1 SIMPLE task1 ref PRIMARY,task_parent,sys_class_name_2,sys_domain_path task_parent 99 test.task2.sys_id 1 NULL 100.00 NULL Using index condition; Using where -1 SIMPLE sysapproval_approver0 ref sysapproval_approver_ref5,sys_domain_path,sysapproval_approver_CHG1975376 sysapproval_approver_ref5 99 test.task1.sys_id 1 NULL 100.00 NULL Using index condition; Using where +1 SIMPLE task1 ref PRIMARY,task_parent,sys_class_name_2,sys_domain_path task_parent 99 test.task2.sys_id 2 NULL 100.00 NULL Using index condition; Using where +1 SIMPLE sysapproval_approver0 ref sysapproval_approver_ref5,sys_domain_path,sysapproval_approver_CHG1975376 sysapproval_approver_ref5 99 test.task1.sys_id 3 NULL 100.00 NULL Using index condition; Using where set optimizer_use_condition_selectivity=4; analyze SELECT sysapproval_approver0.`sys_id` FROM ((sysapproval_approver sysapproval_approver0 @@ -47,9 +47,9 @@ WHERE task2.`sys_id` LIKE '8e7792a7dbfffb00fff8a345ca961934%' ORDER BY sysapproval_approver0.`order` LIMIT 0, 50 ; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE task2 range PRIMARY,sys_class_name_2,sys_domain_path PRIMARY 96 NULL 1 0.00 98.00 100.00 Using where; Using temporary; Using filesort -1 SIMPLE task1 ref PRIMARY,task_parent,sys_class_name_2,sys_domain_path task_parent 99 test.task2.sys_id 1 NULL 100.00 NULL Using index condition; Using where -1 SIMPLE sysapproval_approver0 ref sysapproval_approver_ref5,sys_domain_path,sysapproval_approver_CHG1975376 sysapproval_approver_ref5 99 test.task1.sys_id 1 NULL 100.00 NULL Using index condition; Using where +1 SIMPLE task2 range PRIMARY,sys_class_name_2,sys_domain_path PRIMARY 96 NULL 1 0.00 100.00 100.00 Using where; Using temporary; Using filesort +1 SIMPLE task1 ref PRIMARY,task_parent,sys_class_name_2,sys_domain_path task_parent 99 test.task2.sys_id 2 NULL 100.00 NULL Using index condition; Using where +1 SIMPLE sysapproval_approver0 ref sysapproval_approver_ref5,sys_domain_path,sysapproval_approver_CHG1975376 sysapproval_approver_ref5 99 test.task1.sys_id 3 NULL 100.00 NULL Using index condition; Using where drop table sysapproval_approver,task; set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= diff --git a/mysql-test/main/merge.result b/mysql-test/main/merge.result index 230fcf48e9d..820372efe85 100644 --- a/mysql-test/main/merge.result +++ b/mysql-test/main/merge.result @@ -2804,8 +2804,6 @@ CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST; CREATE TRIGGER tm1_ai AFTER INSERT ON tm1 FOR EACH ROW SELECT max(c1) FROM t1 INTO @var; -Warnings: -Warning 1287 ' INTO FROM...' instead LOCK TABLE tm1 WRITE, t1 WRITE; INSERT INTO tm1 VALUES (1); SELECT * FROM tm1; @@ -2830,8 +2828,6 @@ CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2,t3,t4,t5) INSERT_METHOD=LAST; CREATE TRIGGER t2_au AFTER UPDATE ON t2 FOR EACH ROW SELECT MAX(c1) FROM t1 INTO @var; -Warnings: -Warning 1287 ' INTO FROM...' instead CREATE FUNCTION f1() RETURNS INT RETURN (SELECT MAX(c1) FROM t4); LOCK TABLE tm1 WRITE, t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE, t5 WRITE; @@ -3929,3 +3925,34 @@ drop table tm, t; # # End of 10.8 tests # +# +# MDEV-30088 Assertion `cond_selectivity <= 1.0' failed in get_range_limit_read_cost +# +CREATE TABLE t1 (a TIMESTAMP, KEY(a)) ENGINE=MRG_MyISAM; +explain SELECT a, COUNT(*) FROM t1 WHERE a >= '2000-01-01 00:00:00' GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +SELECT a, COUNT(*) FROM t1 WHERE a >= '2000-01-01 00:00:00' GROUP BY a; +a COUNT(*) +DROP TABLE t1; +# +# MDEV-30525: Assertion `ranges > 0' fails in IO_AND_CPU_COST handler::keyread_time +# +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE tm (a INT, KEY(a)) ENGINE=MRG_MyISAM UNION=(t1,t2); +SELECT DISTINCT a FROM tm WHERE a > 50; +a +DROP TABLE tm, t1, t2; +# +# MDEV-30568 Assertion `cond_selectivity <= 1.000000001' failed in get_range_limit_read_cost +# +CREATE TABLE t1 (f INT, KEY(f)) ENGINE=MyISAM; +CREATE TABLE t2 (f INT, KEY(f)) ENGINE=MyISAM; +CREATE TABLE tm (f INT, KEY(f)) ENGINE=MERGE UNION = (t1, t2); +SELECT DISTINCT f FROM tm WHERE f IN (47, 126, 97, 48, 73, 0); +f +DROP TABLE tm, t1, t2; +# +# End of 11.0 tests +# diff --git a/mysql-test/main/merge.test b/mysql-test/main/merge.test index 0485f3ed1c3..8da9e7b3a1c 100644 --- a/mysql-test/main/merge.test +++ b/mysql-test/main/merge.test @@ -2886,3 +2886,34 @@ drop table tm, t; --echo # --echo # End of 10.8 tests --echo # + +--echo # +--echo # MDEV-30088 Assertion `cond_selectivity <= 1.0' failed in get_range_limit_read_cost +--echo # + +CREATE TABLE t1 (a TIMESTAMP, KEY(a)) ENGINE=MRG_MyISAM; +explain SELECT a, COUNT(*) FROM t1 WHERE a >= '2000-01-01 00:00:00' GROUP BY a; +SELECT a, COUNT(*) FROM t1 WHERE a >= '2000-01-01 00:00:00' GROUP BY a; +DROP TABLE t1; + +--echo # +--echo # MDEV-30525: Assertion `ranges > 0' fails in IO_AND_CPU_COST handler::keyread_time +--echo # +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE tm (a INT, KEY(a)) ENGINE=MRG_MyISAM UNION=(t1,t2); +SELECT DISTINCT a FROM tm WHERE a > 50; +DROP TABLE tm, t1, t2; + +--echo # +--echo # MDEV-30568 Assertion `cond_selectivity <= 1.000000001' failed in get_range_limit_read_cost +--echo # +CREATE TABLE t1 (f INT, KEY(f)) ENGINE=MyISAM; +CREATE TABLE t2 (f INT, KEY(f)) ENGINE=MyISAM; +CREATE TABLE tm (f INT, KEY(f)) ENGINE=MERGE UNION = (t1, t2); +SELECT DISTINCT f FROM tm WHERE f IN (47, 126, 97, 48, 73, 0); +DROP TABLE tm, t1, t2; + +--echo # +--echo # End of 11.0 tests +--echo # diff --git a/mysql-test/main/metadata.result b/mysql-test/main/metadata.result index 5786e2fd461..ab28cab52cb 100644 --- a/mysql-test/main/metadata.result +++ b/mysql-test/main/metadata.result @@ -147,7 +147,7 @@ id data data 2 female no select t1.id from t1 union select t2.id from t2; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def id id 246 4 1 Y 32768 0 63 +def id id 246 4 1 Y 49152 0 63 id 1 2 @@ -158,7 +158,7 @@ insert into t1 values (2,'two'); set @arg00=1 ; select @arg00 FROM t1 where a=1 union distinct select 1 FROM t1 where a=1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg00 @arg00 8 20 1 Y 32768 0 63 +def @arg00 @arg00 8 20 1 Y 49152 0 63 @arg00 1 select * from (select @arg00) aaa; @@ -168,12 +168,12 @@ def aaa @arg00 @arg00 8 20 1 Y 32768 0 63 1 select 1 union select 1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def 1 1 3 1 1 N 32769 0 63 +def 1 1 3 1 1 N 49153 0 63 1 1 select * from (select 1 union select 1) aaa; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def aaa 1 1 3 1 1 N 32769 0 63 +def aaa 1 1 3 1 1 N 49153 0 63 1 1 drop table t1; diff --git a/mysql-test/main/mrr_derived_crash_4610.result b/mysql-test/main/mrr_derived_crash_4610.result index 3e38a0d4218..d7800e8a2a9 100644 --- a/mysql-test/main/mrr_derived_crash_4610.result +++ b/mysql-test/main/mrr_derived_crash_4610.result @@ -7,7 +7,7 @@ explain select 1 from (select f2, f3, val, count(id) from t4 join t2 left join t3 on 0) top join t1 on f1 = f3 where f3 = 'aaaa' order by val; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 const PRIMARY PRIMARY 12 const 1 Using index +1 PRIMARY t1 const PRIMARY PRIMARY 12 const 1 1 PRIMARY ref key0 key0 13 const 0 Using where; Using filesort 2 DERIVED t4 ALL NULL NULL NULL NULL 1 2 DERIVED t2 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) diff --git a/mysql-test/main/multi_update.test b/mysql-test/main/multi_update.test index 54c64918e03..6ec3de6a78b 100644 --- a/mysql-test/main/multi_update.test +++ b/mysql-test/main/multi_update.test @@ -1121,12 +1121,15 @@ INSERT INTO t1 (part,a,b) VALUES (0,0,0),(1,1,1),(2,2,2); INSERT INTO t2 (part,a,b) VALUES (0,0,0),(1,1,1),(2,2,2); --echo # Expecting partition "Current" +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON UPDATE t2 JOIN t1 USING(a) SET t2.part=3 WHERE t2.part=0 AND t1.part=0; --echo # Expecting partition "Relevant" +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON UPDATE t2 JOIN t1 USING(a) SET t2.part=2 WHERE t2.part=1 AND t1.part=1; --echo # Expecting partition "Archive" +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON UPDATE t2 JOIN t1 USING(a) SET t2.part=3 WHERE t2.part=2 AND t1.part=2; DROP TABLES t1, t2; diff --git a/mysql-test/main/myisam.result b/mysql-test/main/myisam.result index 0b0099d7b84..477434e2a5c 100644 --- a/mysql-test/main/myisam.result +++ b/mysql-test/main/myisam.result @@ -348,11 +348,11 @@ t1 1 c_2 2 a A 5 NULL NULL BTREE NO explain select * from t1,t2 where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL a NULL NULL NULL 2 -1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ref a a 4 test.t2.a 3 explain select * from t1,t2 force index(a) where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL a NULL NULL NULL 2 -1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ref a a 4 test.t2.a 3 explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL a NULL NULL NULL 2 @@ -388,10 +388,10 @@ t1 1 c_2 2 a A 5 NULL NULL BTREE NO explain select * from t1,t2 force index(c) where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 -1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ref a a 4 test.t2.a 3 explain select * from t1 where a=0 or a=2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where +1 SIMPLE t1 range a a 4 NULL 5 Using index condition explain select * from t1 force index (a) where a=0 or a=2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 4 NULL 5 Using index condition @@ -644,6 +644,13 @@ id select_type table type possible_keys key key_len ref rows Extra select count(*) from t1 where a is null; count(*) 2 +insert into t1 values (1,''), (2,''); +explain select count(*) from t1 where a is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx idx 4 const 2 Using where +set statement optimizer_scan_setup_cost= 0 for explain select count(*) from t1 where a is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL idx NULL NULL NULL 4 Using where drop table t1; create table t1 (c1 int, c2 varchar(4) not null default '', key(c2(3))) default charset=utf8; @@ -2532,6 +2539,7 @@ DROP TABLE t1, t2, t3; # # BUG#51307 - widespread corruption with partitions and insert...select # +call mtr.add_suppression("Enabling keys got errno 12 on test.t1, retrying"); CREATE TABLE t1(a CHAR(255), KEY(a)); SELECT * FROM t1, t1 AS a1; a a @@ -2810,3 +2818,44 @@ drop table t; # # End of 10.8 tests # +CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY(pk), KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,5); +SET @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='index_merge_sort_intersection=on'; +SELECT pk FROM t1 WHERE pk > 2 AND a IS NULL; +pk +SET @@optimizer_switch= @save_optimizer_switch; +drop table t1; +# +# MDEV-30104 Server crashes in handler_rowid_filter_check upon ANALYZE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1),(2); +CREATE TABLE t3 (c INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1),(2); +CREATE TABLE t4 (pk INT, f CHAR(8), PRIMARY KEY(pk), KEY(f)) ENGINE=MyISAM; +INSERT INTO t4 VALUES (1,'o'),(2,'x'); +ANALYZE TABLE t1, t2, t3, t4 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +test.t4 analyze status Engine-independent statistics collected +test.t4 analyze status OK +SELECT * FROM t1 LEFT JOIN (t2 JOIN t3 ON 1) ON 2 IN (SELECT pk FROM t4 WHERE f < 's'); +a b c +1 NULL NULL +2 NULL NULL +ANALYZE TABLE t4 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t4 analyze status Engine-independent statistics collected +test.t4 analyze status Table is already up to date +DROP TABLE t1, t2, t3, t4; +# +# End of 11.0 tests +# diff --git a/mysql-test/main/myisam.test b/mysql-test/main/myisam.test index ec49e71bc2d..1a20f97a54f 100644 --- a/mysql-test/main/myisam.test +++ b/mysql-test/main/myisam.test @@ -593,6 +593,9 @@ create table t1 ( a tinytext, b char(1), index idx (a(1),b) ); insert into t1 values (null,''), (null,''); explain select count(*) from t1 where a is null; select count(*) from t1 where a is null; +insert into t1 values (1,''), (2,''); +explain select count(*) from t1 where a is null; +set statement optimizer_scan_setup_cost= 0 for explain select count(*) from t1 where a is null; drop table t1; # @@ -1676,6 +1679,9 @@ DROP TABLE t1, t2, t3; --echo # --echo # BUG#51307 - widespread corruption with partitions and insert...select --echo # + +call mtr.add_suppression("Enabling keys got errno 12 on test.t1, retrying"); + CREATE TABLE t1(a CHAR(255), KEY(a)); SELECT * FROM t1, t1 AS a1; SET myisam_sort_buffer_size=4; @@ -1910,3 +1916,38 @@ drop table t; --echo # --echo # End of 10.8 tests --echo # + +CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY(pk), KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,5); +SET @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='index_merge_sort_intersection=on'; +SELECT pk FROM t1 WHERE pk > 2 AND a IS NULL; +SET @@optimizer_switch= @save_optimizer_switch; +drop table t1; + +--echo # +--echo # MDEV-30104 Server crashes in handler_rowid_filter_check upon ANALYZE TABLE +--echo # + +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (b INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1),(2); # Optional, fails either way + +CREATE TABLE t3 (c INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1),(2); # Optional, fails either way + +CREATE TABLE t4 (pk INT, f CHAR(8), PRIMARY KEY(pk), KEY(f)) ENGINE=MyISAM; +INSERT INTO t4 VALUES (1,'o'),(2,'x'); + +ANALYZE TABLE t1, t2, t3, t4 PERSISTENT FOR ALL; # Optional, fails either way +SELECT * FROM t1 LEFT JOIN (t2 JOIN t3 ON 1) ON 2 IN (SELECT pk FROM t4 WHERE f < 's'); + +ANALYZE TABLE t4 PERSISTENT FOR ALL; + +DROP TABLE t1, t2, t3, t4; + +--echo # +--echo # End of 11.0 tests +--echo # diff --git a/mysql-test/main/myisam_debug.result b/mysql-test/main/myisam_debug.result index 10208a936a0..698a45294c0 100644 --- a/mysql-test/main/myisam_debug.result +++ b/mysql-test/main/myisam_debug.result @@ -23,8 +23,6 @@ SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'wait_in_enable_indexes' AND INFO = "INSERT INTO t1(id) SELECT id FROM t2" INTO @thread_id; -Warnings: -Warning 1287 ' INTO FROM...' instead KILL QUERY @thread_id; CHECK TABLE t1; Table Op Msg_type Msg_text diff --git a/mysql-test/main/myisam_explain_non_select_all.result b/mysql-test/main/myisam_explain_non_select_all.result index 2ff966fdfd3..82d494be01c 100644 --- a/mysql-test/main/myisam_explain_non_select_all.result +++ b/mysql-test/main/myisam_explain_non_select_all.result @@ -7,8 +7,6 @@ INSERT INTO t1 VALUES (1), (2), (3); # query: UPDATE t1 SET a = 10 WHERE a < 10 # select: SELECT * FROM t1 WHERE a < 10 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET a = 10 WHERE a < 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where @@ -30,8 +28,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -50,8 +46,6 @@ INSERT INTO t1 VALUES (1), (2), (3); # query: DELETE FROM t1 WHERE a < 10 # select: SELECT * FROM t1 WHERE a < 10 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE a < 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where @@ -73,8 +67,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -93,8 +85,6 @@ INSERT INTO t1 VALUES (1), (2), (3); # query: DELETE FROM t1 USING t1 WHERE a = 1 # select: SELECT * FROM t1 WHERE a = 1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 USING t1 WHERE a = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where @@ -116,8 +106,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -138,8 +126,6 @@ INSERT INTO t2 VALUES (1), (2), (3); # query: UPDATE t1, t2 SET t1.a = 10 WHERE t1.a = 1 # select: SELECT * FROM t1, t2 WHERE t1.a = 1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1, t2 SET t1.a = 10 WHERE t1.a = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where @@ -164,8 +150,6 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -186,8 +170,6 @@ INSERT INTO t2 VALUES (1), (2), (3); # query: UPDATE t1 t11, (SELECT * FROM t2) t12 SET t11.a = 10 WHERE t11.a = 1 # select: SELECT * FROM t1 t11, (SELECT * FROM t2) t12 WHERE t11.a = 1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 t11, (SELECT * FROM t2) t12 SET t11.a = 10 WHERE t11.a = 1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t11 ALL NULL NULL NULL NULL 3 Using where @@ -214,8 +196,6 @@ Note 1003 select `test`.`t11`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -236,8 +216,6 @@ INSERT INTO t2 VALUES (1), (2), (3); # query: UPDATE t1 SET a = 10 WHERE 1 IN (SELECT 1 FROM t2 WHERE t2.b < 3) # select: SELECT * FROM t1 WHERE 1 IN (SELECT 1 FROM t2 WHERE t2.b < 3) # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET a = 10 WHERE 1 IN (SELECT 1 FROM t2 WHERE t2.b < 3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 @@ -256,20 +234,17 @@ FLUSH STATUS; FLUSH TABLES; EXPLAIN EXTENDED SELECT * FROM t1 WHERE 1 IN (SELECT 1 FROM t2 WHERE t2.b < 3); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 33.33 Using where; FirstMatch 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`b` < 3 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value -Handler_read_key 5 -Handler_read_rnd_next 8 +Handler_read_key 4 +Handler_read_rnd_next 5 # Status of testing query execution: Variable_name Value Handler_read_key 4 @@ -286,8 +261,6 @@ INSERT INTO t2 VALUES (1), (2), (3); # query: UPDATE t1 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t1.a < 3) # select: SELECT * FROM t1 WHERE a IN (SELECT b FROM t2 WHERE t1.a < 3) # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t1.a < 3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where @@ -315,8 +288,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -328,60 +299,59 @@ Handler_read_rnd_next 7 Handler_update 2 DROP TABLE t1, t2; -#7 +#7a CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); CREATE TABLE t2 (b INT); -INSERT INTO t2 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (1), (2), (3), (1000); +CREATE TABLE t3 like t2; +insert into t3 select * from t2; +insert into t3 select seq from seq_1001_to_2000; # -# query: UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3) -# select: SELECT * FROM t1, t2 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3) +# query: UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t3 WHERE t3.b < 3) +# select: SELECT * FROM t1, t2 WHERE a IN (SELECT b FROM t3 WHERE t3.b < 3) # -Warnings: -Warning 1287 ' INTO FROM...' instead -EXPLAIN UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3); +EXPLAIN UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t3 WHERE t3.b < 3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -1 PRIMARY t2 ALL NULL NULL NULL NULL 3 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 1004 Using where FLUSH STATUS; FLUSH TABLES; -EXPLAIN EXTENDED UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3); +EXPLAIN EXTENDED UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT b FROM t3 WHERE t3.b < 3); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 100.00 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 1004 100.00 Using where # Status of EXPLAIN EXTENDED query Variable_name Value -Handler_read_key 4 +Handler_read_key 6 FLUSH STATUS; FLUSH TABLES; -EXPLAIN EXTENDED SELECT * FROM t1, t2 WHERE a IN (SELECT b FROM t2 WHERE t2.b < 3); +EXPLAIN EXTENDED SELECT * FROM t1, t2 WHERE a IN (SELECT b FROM t3 WHERE t3.b < 3); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join) +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 1004 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2`) join `test`.`t2` where `test`.`t2`.`b` < 3 +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) join `test`.`t2` where `test`.`t3`.`b` < 3 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value -Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead +Handler_read_key 6 # Status of "equivalent" SELECT query execution: Variable_name Value -Handler_read_key 7 -Handler_read_rnd_next 12 +Handler_read_key 9 +Handler_read_rnd_next 1014 # Status of testing query execution: Variable_name Value -Handler_read_key 7 -Handler_read_rnd_next 16 +Handler_read_key 9 +Handler_read_rnd_next 1019 Handler_update 2 -DROP TABLE t1, t2; +DROP TABLE t1, t2, t3; #8 CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); @@ -391,8 +361,6 @@ INSERT INTO t2 VALUES (1), (2), (3); # query: UPDATE t1 t11, (SELECT * FROM t2) t12 SET t11.a = t11.a + 10 # select: SELECT * FROM t1 t11, (SELECT * FROM t2) t12 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 t11, (SELECT * FROM t2) t12 SET t11.a = t11.a + 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t11 ALL NULL NULL NULL NULL 3 @@ -419,8 +387,6 @@ Note 1003 select `test`.`t11`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -443,8 +409,6 @@ INSERT INTO t2 VALUES (1), (2), (3); # query: UPDATE t1 t11, (SELECT 1 FROM DUAL) t12 SET t11.a = t11.a + 10 # select: SELECT * FROM t1 t11, (SELECT 1 FROM DUAL) t12 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 t11, (SELECT 1 FROM DUAL) t12 SET t11.a = t11.a + 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 @@ -474,8 +438,6 @@ Note 1003 /* select#1 */ select `test`.`t11`.`a` AS `a`,1 AS `1` from `test`.`t1 Variable_name Value Handler_read_key 2 Handler_read_rnd_next 1 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -497,8 +459,6 @@ INSERT INTO t2 VALUES (1), (2), (3); # query: UPDATE t1 t11, (SELECT * FROM t2) t12 SET t11.a = 10 WHERE t11.a > 1 # select: SELECT * FROM t1 t11, (SELECT * FROM t2) t12 WHERE t11.a > 1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 t11, (SELECT * FROM t2) t12 SET t11.a = 10 WHERE t11.a > 1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t11 ALL NULL NULL NULL NULL 3 Using where @@ -525,8 +485,6 @@ Note 1003 select `test`.`t11`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -545,8 +503,6 @@ INSERT INTO t1 VALUES (1), (2), (3); # query: DELETE FROM t1 WHERE a > 1 LIMIT 1 # select: SELECT * FROM t1 WHERE a > 1 LIMIT 1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE a > 1 LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where @@ -568,8 +524,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -588,8 +542,6 @@ INSERT INTO t1 VALUES (1), (2), (3); # query: DELETE FROM t1 WHERE 0 # select: SELECT * FROM t1 WHERE 0 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE @@ -611,8 +563,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -628,8 +578,6 @@ INSERT INTO t1 VALUES (1), (2), (3); # query: DELETE FROM t1 USING t1 WHERE 0 # select: SELECT * FROM t1 WHERE 0 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 USING t1 WHERE 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE @@ -651,8 +599,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -668,8 +614,6 @@ INSERT INTO t1 VALUES (3, 3), (7, 7); # query: DELETE FROM t1 WHERE a = 3 # select: SELECT * FROM t1 WHERE a = 3 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE a = 3; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 1 Using where @@ -691,8 +635,6 @@ Note 1003 select 3 AS `a`,3 AS `b` from `test`.`t1` where 1 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 6 @@ -709,8 +651,6 @@ INSERT INTO t1 VALUES (3, 3), (7, 7); # query: DELETE FROM t1 WHERE a < 3 # select: SELECT * FROM t1 WHERE a < 3 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE a < 3; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 1 Using where @@ -732,8 +672,6 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 5 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 6 @@ -748,8 +686,6 @@ CREATE TABLE t1 ( a int PRIMARY KEY ); # query: DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a # select: SELECT * FROM t1 WHERE t1.a > 0 ORDER BY t1.a # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE @@ -772,8 +708,6 @@ Note 1003 select NULL AS `a` from `test`.`t1` where 0 order by NULL Variable_name Value Handler_read_key 3 Handler_read_rnd_next 1 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 3 @@ -787,8 +721,6 @@ INSERT INTO t1 VALUES (1), (2), (3), (-1), (-2), (-3); # query: DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a # select: SELECT * FROM t1 WHERE t1.a > 0 ORDER BY t1.a # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where @@ -810,8 +742,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 3 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -830,8 +760,6 @@ INSERT INTO t1 VALUES (4),(3),(1),(2); # query: DELETE FROM t1 WHERE (@a:= a) ORDER BY a LIMIT 1 # select: SELECT * FROM t1 WHERE (@a:= a) ORDER BY a LIMIT 1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE (@a:= a) ORDER BY a LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL 1 Using where @@ -853,8 +781,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where @a:=`test`.`t1`.` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 3 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_first 1 @@ -874,8 +800,6 @@ UPDATE t1 SET a = c, b = c; # query: DELETE FROM t1 ORDER BY a ASC, b ASC LIMIT 1 # select: SELECT * FROM t1 ORDER BY a ASC, b ASC LIMIT 1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 ORDER BY a ASC, b ASC LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using filesort @@ -897,8 +821,6 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 7 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 7 @@ -927,8 +849,6 @@ INSERT INTO t3 VALUES (1,1), (2,1), (1,3); # query: DELETE t1,t2,t3 FROM t1,t2,t3 WHERE a1=a2 AND b2=a3 AND b1=b3 # select: SELECT * FROM t1,t2,t3 WHERE a1=a2 AND b2=a3 AND b1=b3 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE t1,t2,t3 FROM t1,t2,t3 WHERE a1=a2 AND b2=a3 AND b1=b3; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 @@ -956,8 +876,6 @@ Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 13 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 19 @@ -976,23 +894,21 @@ DROP TABLE t1, t2, t3; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); CREATE TABLE t2 (a INT); -INSERT INTO t2 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (1), (2), (3), (1000); # # query: UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2) # select: SELECT * FROM t1 WHERE a IN (SELECT a FROM t2) # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where FLUSH STATUS; FLUSH TABLES; EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using where # Status of EXPLAIN EXTENDED query Variable_name Value Handler_read_key 4 @@ -1001,19 +917,16 @@ FLUSH TABLES; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where 1 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`a` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value -Handler_read_key 7 -Handler_read_rnd_next 8 +Handler_read_key 4 +Handler_read_rnd_next 9 # Status of testing query execution: Variable_name Value Handler_read_key 4 @@ -1031,8 +944,6 @@ SET @save_optimizer_switch= @@optimizer_switch; # query: DELETE FROM t1 WHERE a1 IN (SELECT a2 FROM t2 WHERE a2 > 2) # select: SELECT * FROM t1 WHERE a1 IN (SELECT a2 FROM t2 WHERE a2 > 2) # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE a1 IN (SELECT a2 FROM t2 WHERE a2 > 2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where @@ -1057,8 +968,6 @@ Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1` from `test`.`t1` where # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 9 @@ -1076,8 +985,6 @@ INSERT INTO t1 VALUES (1), (2), (3), (4), (5); # query: DELETE FROM t1 WHERE a1 IN (SELECT a2 FROM t2 WHERE a2 > 2) # select: SELECT * FROM t1 WHERE a1 IN (SELECT a2 FROM t2 WHERE a2 > 2) # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE a1 IN (SELECT a2 FROM t2 WHERE a2 > 2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where @@ -1102,8 +1009,6 @@ Note 1003 select `test`.`t1`.`a1` AS `a1` from `test`.`t1` semi join (`test`.`t2 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -1122,8 +1027,6 @@ INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); # query: UPDATE t1 SET i = 10 # select: SELECT * FROM t1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET i = 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 @@ -1145,8 +1048,6 @@ Note 1003 select `test`.`t1`.`i` AS `i`,`test`.`t1`.`j` AS `j` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 3 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 3 @@ -1165,8 +1066,6 @@ INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); # query: DELETE FROM t1 # select: SELECT * FROM t1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL 5 Deleting all rows @@ -1188,8 +1087,6 @@ Note 1003 select `test`.`t1`.`i` AS `i`,`test`.`t1`.`j` AS `j` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 3 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 3 @@ -1211,8 +1108,6 @@ INSERT INTO t2 (a, b, c) SELECT t1.i, t1.i, t1.i FROM t1, t1 x1, t1 x2; # query: DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL a 15 NULL 5 Using where @@ -1234,8 +1129,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 8 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_first 1 @@ -1257,8 +1150,6 @@ CREATE TABLE t2 (i INT); # query: INSERT INTO t2 SELECT * FROM t1 # select: SELECT * FROM t1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN INSERT INTO t2 SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 @@ -1280,8 +1171,6 @@ Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -1301,8 +1190,6 @@ CREATE TABLE t2 (i INT); # query: REPLACE INTO t2 SELECT * FROM t1 # select: SELECT * FROM t1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN REPLACE INTO t2 SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 @@ -1324,8 +1211,6 @@ Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -1392,8 +1277,6 @@ INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), # query: DELETE FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5 # select: SELECT * FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 5 Using where @@ -1415,8 +1298,6 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`i` AS `i` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 5 @@ -1437,8 +1318,6 @@ INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), # query: DELETE FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5 # select: SELECT * FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using where; Using filesort @@ -1460,8 +1339,6 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`i` AS `i` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -1490,62 +1367,6 @@ INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1; # query: DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead -EXPLAIN DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using where; Using filesort -FLUSH STATUS; -FLUSH TABLES; -EXPLAIN EXTENDED DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; -id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 26 100.00 Using where; Using filesort -# Status of EXPLAIN EXTENDED query -Variable_name Value -Handler_read_key 8 -FLUSH STATUS; -FLUSH TABLES; -EXPLAIN EXTENDED SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; -id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 26 100.00 Using where; Using filesort -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` where `test`.`t2`.`b` = 10 order by `test`.`t2`.`a`,`test`.`t2`.`c` limit 5 -# Status of EXPLAIN EXTENDED "equivalent" SELECT query execution -Variable_name Value -Handler_read_key 8 -Warnings: -Warning 1287 ' INTO FROM...' instead -# Status of "equivalent" SELECT query execution: -Variable_name Value -Handler_read_key 8 -Handler_read_rnd_next 27 -Sort_priority_queue_sorts 1 -Sort_rows 1 -Sort_scan 1 -# Status of testing query execution: -Variable_name Value -Handler_delete 1 -Handler_read_key 8 -Handler_read_rnd 1 -Handler_read_rnd_next 27 -Sort_rows 1 -Sort_scan 1 - -DROP TABLE t1, t2; -#32 -CREATE TABLE t1 (i INT); -INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), -(20),(21),(22),(23),(24),(25),(26),(27),(28),(29), -(30),(31),(32),(33),(34),(35); -CREATE TABLE t2(a INT, b INT, c INT, d INT, INDEX(a, b, c)); -INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1; -INSERT INTO t2 (a, b, c) SELECT t1.i, t1.i, t1.i FROM t1, t1 x1, t1 x2; -# -# query: DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 -# select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 -# -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL a 15 NULL 5 Using where @@ -1567,8 +1388,52 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 8 +# Status of "equivalent" SELECT query execution: +Variable_name Value +Handler_read_first 1 +Handler_read_key 8 +Handler_read_next 26 +# Status of testing query execution: +Variable_name Value +Handler_delete 1 +Handler_read_first 1 +Handler_read_key 8 +Handler_read_next 26 + +DROP TABLE t1, t2; +#32 +CREATE TABLE t1 (i INT); +INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), +(20),(21),(22),(23),(24),(25),(26),(27),(28),(29), +(30),(31),(32),(33),(34),(35); +CREATE TABLE t2(a INT, b INT, c INT, d INT, INDEX(a, b, c)); +INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1; +INSERT INTO t2 (a, b, c) SELECT t1.i, t1.i, t1.i FROM t1, t1 x1, t1 x2; +# +# query: DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 +# select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 +# +EXPLAIN DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL a 15 NULL 5 Using where +FLUSH STATUS; +FLUSH TABLES; +EXPLAIN EXTENDED DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 index NULL a 15 NULL 5 100.00 Using where +# Status of EXPLAIN EXTENDED query +Variable_name Value +Handler_read_key 8 +FLUSH STATUS; +FLUSH TABLES; +EXPLAIN EXTENDED SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 index NULL a 15 NULL 5 100.00 Using where Warnings: -Warning 1287 ' INTO FROM...' instead +Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` where `test`.`t2`.`b` = 10 order by `test`.`t2`.`a`,`test`.`t2`.`c` limit 5 +# Status of EXPLAIN EXTENDED "equivalent" SELECT query execution +Variable_name Value +Handler_read_key 8 # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_first 1 @@ -1593,8 +1458,6 @@ INSERT INTO t2 SELECT i, i, i, i FROM t1; # query: DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using where; Using filesort @@ -1616,8 +1479,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 8 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 8 @@ -1647,8 +1508,6 @@ INSERT INTO t2 SELECT i, i, i, i FROM t1; # query: DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using where; Using filesort @@ -1670,8 +1529,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 8 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 8 @@ -1702,8 +1559,6 @@ INSERT INTO t2 (key1, key2) SELECT i, i FROM t1; # query: DELETE FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1 # select: SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index_merge key1,key2 key1,key2 5,5 NULL 7 Using sort_union(key1,key2); Using where; Using filesort @@ -1725,8 +1580,6 @@ Note 1003 select `test`.`t2`.`i` AS `i`,`test`.`t2`.`key1` AS `key1`,`test`.`t2` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 8 @@ -1755,8 +1608,6 @@ INSERT INTO t2 (i) SELECT i FROM t1; # query: DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5 # select: SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 Using where @@ -1778,8 +1629,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`i` AS `i` from `test`.`t2` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 5 @@ -1802,8 +1651,6 @@ INSERT INTO t2 SELECT i, i, i FROM t1; # query: DELETE FROM t2 ORDER BY a, b DESC LIMIT 5 # select: SELECT * FROM t2 ORDER BY a, b DESC LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t2 ORDER BY a, b DESC LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using filesort @@ -1825,8 +1672,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 6 @@ -1856,8 +1701,6 @@ INSERT INTO t2 (a, b) SELECT t1.i, t1.i FROM t1, t1 x1, t1 x2; # query: DELETE FROM t2 ORDER BY a DESC, b DESC LIMIT 5 # select: SELECT * FROM t2 ORDER BY a DESC, b DESC LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t2 ORDER BY a DESC, b DESC LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL a 6 NULL 5 @@ -1879,8 +1722,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 6 @@ -1905,8 +1746,6 @@ INSERT INTO t2 (i) SELECT i FROM t1; # query: UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5 # select: SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 Using where; Using buffer @@ -1928,8 +1767,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`i` AS `i` from `test`.`t2` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 5 @@ -1953,8 +1790,6 @@ INSERT INTO t2 (i) SELECT i FROM t1; # query: UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5 # select: SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using where; Using filesort @@ -1976,8 +1811,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`i` AS `i` from `test`.`t2` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -2007,63 +1840,6 @@ INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1; # query: UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5 # select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead -EXPLAIN UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using where; Using filesort -FLUSH STATUS; -FLUSH TABLES; -EXPLAIN EXTENDED UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; -id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 26 100.00 Using where; Using filesort -# Status of EXPLAIN EXTENDED query -Variable_name Value -Handler_read_key 8 -FLUSH STATUS; -FLUSH TABLES; -EXPLAIN EXTENDED SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; -id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 26 100.00 Using where; Using filesort -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` where `test`.`t2`.`b` = 10 order by `test`.`t2`.`a`,`test`.`t2`.`c` limit 5 -# Status of EXPLAIN EXTENDED "equivalent" SELECT query execution -Variable_name Value -Handler_read_key 8 -Warnings: -Warning 1287 ' INTO FROM...' instead -# Status of "equivalent" SELECT query execution: -Variable_name Value -Handler_read_key 8 -Handler_read_rnd_next 27 -Sort_priority_queue_sorts 1 -Sort_rows 1 -Sort_scan 1 -# Status of testing query execution: -Variable_name Value -Handler_read_key 8 -Handler_read_rnd 1 -Handler_read_rnd_next 27 -Handler_update 1 -Sort_priority_queue_sorts 1 -Sort_rows 1 -Sort_scan 1 - -DROP TABLE t1, t2; -#42 -CREATE TABLE t1 (i INT); -INSERT INTO t1 VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), -(20),(21),(22),(23),(24),(25),(26),(27),(28),(29), -(30),(31),(32),(33),(34),(35); -CREATE TABLE t2(a INT, b INT, c INT, d INT, INDEX(a, b, c)); -INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1; -INSERT INTO t2 (a, b, c) SELECT t1.i, t1.i, t1.i FROM t1, t1 x1, t1 x2; -# -# query: UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5 -# select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 -# -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL a 15 NULL 5 Using where; Using buffer @@ -2085,8 +1861,53 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 8 +# Status of "equivalent" SELECT query execution: +Variable_name Value +Handler_read_first 1 +Handler_read_key 8 +Handler_read_next 26 +# Status of testing query execution: +Variable_name Value +Handler_read_first 1 +Handler_read_key 8 +Handler_read_next 26 +Handler_read_rnd 1 +Handler_update 1 + +DROP TABLE t1, t2; +#42 +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19), +(20),(21),(22),(23),(24),(25),(26),(27),(28),(29), +(30),(31),(32),(33),(34),(35); +CREATE TABLE t2(a INT, b INT, c INT, d INT, INDEX(a, b, c)); +INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1; +INSERT INTO t2 (a, b, c) SELECT t1.i, t1.i, t1.i FROM t1, t1 x1, t1 x2; +# +# query: UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5 +# select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 +# +EXPLAIN UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL a 15 NULL 5 Using where; Using buffer +FLUSH STATUS; +FLUSH TABLES; +EXPLAIN EXTENDED UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 index NULL a 15 NULL 5 100.00 Using where; Using buffer +# Status of EXPLAIN EXTENDED query +Variable_name Value +Handler_read_key 8 +FLUSH STATUS; +FLUSH TABLES; +EXPLAIN EXTENDED SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 index NULL a 15 NULL 5 100.00 Using where Warnings: -Warning 1287 ' INTO FROM...' instead +Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` where `test`.`t2`.`b` = 10 order by `test`.`t2`.`a`,`test`.`t2`.`c` limit 5 +# Status of EXPLAIN EXTENDED "equivalent" SELECT query execution +Variable_name Value +Handler_read_key 8 # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_first 1 @@ -2112,8 +1933,6 @@ INSERT INTO t2 SELECT i, i, i, i FROM t1; # query: UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5 # select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using where; Using filesort @@ -2135,8 +1954,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 8 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 8 @@ -2166,8 +1983,6 @@ INSERT INTO t2 SELECT i, i, i, i FROM t1; # query: UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5 # select: SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using where; Using filesort @@ -2189,8 +2004,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 8 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 8 @@ -2221,8 +2034,6 @@ INSERT INTO t2 (key1, key2) SELECT i, i FROM t1; # query: UPDATE t2 SET i = 123 WHERE key1 < 13 or key2 < 14 ORDER BY key1 # select: SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET i = 123 WHERE key1 < 13 or key2 < 14 ORDER BY key1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index_merge key1,key2 key1,key2 5,5 NULL 7 Using sort_union(key1,key2); Using where; Using filesort @@ -2244,8 +2055,6 @@ Note 1003 select `test`.`t2`.`i` AS `i`,`test`.`t2`.`key1` AS `key1`,`test`.`t2` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 8 @@ -2274,8 +2083,6 @@ INSERT INTO t2 (i) SELECT i FROM t1; # query: UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5 # select: SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 Using where; Using buffer @@ -2297,8 +2104,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`i` AS `i` from `test`.`t2` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 5 @@ -2322,8 +2127,6 @@ INSERT INTO t2 SELECT i, i, i FROM t1; # query: UPDATE t2 SET c = 10 ORDER BY a, b DESC LIMIT 5 # select: SELECT * FROM t2 ORDER BY a, b DESC LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET c = 10 ORDER BY a, b DESC LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 26 Using filesort @@ -2345,8 +2148,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 6 @@ -2377,8 +2178,6 @@ INSERT INTO t2 (a, b) SELECT t1.i, t1.i FROM t1, t1 x1, t1 x2; # query: UPDATE t2 SET c = 10 ORDER BY a DESC, b DESC LIMIT 5 # select: SELECT * FROM t2 ORDER BY a DESC, b DESC LIMIT 5 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t2 SET c = 10 ORDER BY a DESC, b DESC LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL a 6 NULL 5 Using buffer @@ -2400,8 +2199,6 @@ Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` A # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 6 @@ -2429,8 +2226,6 @@ INSERT INTO t1 VALUES (1,'y',1), (2,'n',2), (3,'y',3), (4,'n',4); # query: UPDATE t1 SET c2 = 0 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2 # select: SELECT * FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET c2 = 0 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range c1_idx c1_idx 2 NULL 2 Using where; Using filesort @@ -2452,8 +2247,6 @@ Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1_idx` AS `c1_idx`,`test # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 7 @@ -2475,8 +2268,6 @@ Sort_rows 2 # query: DELETE FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2 # select: SELECT * FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range c1_idx c1_idx 2 NULL 2 Using where; Using filesort @@ -2498,8 +2289,6 @@ Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1_idx` AS `c1_idx`,`test # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 7 @@ -2524,8 +2313,6 @@ INSERT INTO t1 VALUES (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),( # query: UPDATE t1 SET a=a+10 WHERE a > 34 # select: SELECT * FROM t1 WHERE a > 34 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET a=a+10 WHERE a > 34; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using buffer @@ -2547,8 +2334,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 3 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -2569,8 +2354,6 @@ INSERT INTO t1 VALUES (1, 1, 10), (2, 2, 20); # query: UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t2.c2 = 10 # select: SELECT * FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t2.c2 = 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found @@ -2597,8 +2380,6 @@ Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.` Variable_name Value Handler_read_key 7 Handler_read_rnd_next 1 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 7 @@ -2612,8 +2393,6 @@ Handler_read_rnd_next 4 # query: UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t2.c2 = 10 WHERE t1.c3 = 10 # select: SELECT * FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c3 = 10 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t2.c2 = 10 WHERE t1.c3 = 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found @@ -2640,8 +2419,6 @@ Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.` Variable_name Value Handler_read_key 7 Handler_read_rnd_next 1 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 7 @@ -2662,18 +2439,16 @@ INSERT INTO t2 VALUES(1,1),(2,2); # query: UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1) # select: SELECT (SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1) FROM t1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -2 DEPENDENT SUBQUERY t2 ALL IDX NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ref IDX IDX 5 test.t1.f1 1 FLUSH STATUS; FLUSH TABLES; EXPLAIN EXTENDED UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -2 DEPENDENT SUBQUERY t2 ALL IDX NULL NULL NULL 2 100.00 Using where +2 DEPENDENT SUBQUERY t2 ref IDX IDX 5 test.t1.f1 1 100.00 Warnings: Note 1276 Field or reference 'test.t1.f1' of SELECT #2 was resolved in SELECT #1 # Status of EXPLAIN EXTENDED query @@ -2684,23 +2459,23 @@ FLUSH TABLES; EXPLAIN EXTENDED SELECT (SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1) FROM t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -2 DEPENDENT SUBQUERY t2 ALL IDX NULL NULL NULL 2 100.00 Using where +2 DEPENDENT SUBQUERY t2 ref IDX IDX 5 test.t1.f1 1 100.00 Warnings: Note 1276 Field or reference 'test.t1.f1' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select <`test`.`t1`.`f1`>((/* select#2 */ select max(`test`.`t2`.`f4`) from `test`.`t2` where `test`.`t2`.`f3` = `test`.`t1`.`f1`)) AS `(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1)` from `test`.`t1` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 7 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value -Handler_read_key 9 -Handler_read_rnd_next 9 +Handler_read_key 11 +Handler_read_next 2 +Handler_read_rnd_next 3 # Status of testing query execution: Variable_name Value -Handler_read_key 7 -Handler_read_rnd_next 9 +Handler_read_key 9 +Handler_read_next 2 +Handler_read_rnd_next 3 Handler_update 2 DROP TABLE t1, t2; @@ -2735,8 +2510,6 @@ CREATE VIEW v1 AS SELECT t11.a, t12.a AS b FROM t1 t11, t1 t12; # query: UPDATE v1 SET a = 1 WHERE a > 0 # select: SELECT * FROM v1 WHERE a > 0 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE v1 SET a = 1 WHERE a > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t11 ALL NULL NULL NULL NULL 2 Using where @@ -2761,8 +2534,6 @@ Note 1003 select `test`.`t11`.`a` AS `a`,`test`.`t12`.`a` AS `b` from `test`.`t1 # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -2778,8 +2549,6 @@ Handler_read_rnd_next 8 # query: UPDATE t1, v1 SET v1.a = 1 WHERE t1.a = v1.a # select: SELECT * FROM t1, v1 WHERE t1.a = v1.a # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1, v1 SET v1.a = 1 WHERE t1.a = v1.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 @@ -2807,8 +2576,6 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t11`.`a` AS `a`,`test`.`t12`.`a` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 2 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -2831,8 +2598,6 @@ CREATE VIEW v1 (a) AS SELECT a FROM t1; # query: DELETE FROM v1 WHERE a < 4 # select: SELECT * FROM v1 WHERE a < 4 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE FROM v1 WHERE a < 4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where @@ -2854,8 +2619,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 3 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_first 1 @@ -2880,8 +2643,6 @@ CREATE VIEW v1 (a,c) AS SELECT a, b+1 FROM t1; # query: DELETE v1 FROM t2, v1 WHERE t2.x = v1.a # select: SELECT * FROM t2, v1 WHERE t2.x = v1.a # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE v1 FROM t2, v1 WHERE t2.x = v1.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where @@ -2906,8 +2667,6 @@ Note 1003 select `test`.`t2`.`x` AS `x`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` + # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 10 @@ -2931,8 +2690,6 @@ CREATE VIEW v1 (a,c) AS SELECT a, b+1 FROM t1; # query: DELETE v1 FROM t2, v1 WHERE t2.x = v1.a # select: SELECT * FROM t2, v1 WHERE t2.x = v1.a # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN DELETE v1 FROM t2, v1 WHERE t2.x = v1.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where @@ -2957,8 +2714,6 @@ Note 1003 select `test`.`t2`.`x` AS `x`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` + # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 6 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 10 @@ -3017,8 +2772,6 @@ CREATE VIEW v1 (x) AS SELECT b FROM t2; # query: INSERT INTO v1 SELECT * FROM t1 # select: SELECT * FROM t1 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN INSERT INTO v1 SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found @@ -3042,8 +2795,6 @@ Note 1003 select NULL AS `a` from `test`.`t1` Variable_name Value Handler_read_key 2 Handler_read_rnd_next 1 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 2 @@ -3070,19 +2821,17 @@ INSERT INTO t2 VALUES (1), (2), (3); # query: UPDATE t1 SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x) # select: SELECT * FROM t1 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x) # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY index_subquery key0 key0 5 func 2 +2 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 5 func 1 3 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort FLUSH STATUS; FLUSH TABLES; EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -2 DEPENDENT SUBQUERY index_subquery key0 key0 5 func 2 100.00 +2 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 5 func 1 100.00 3 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using filesort # Status of EXPLAIN EXTENDED query Variable_name Value @@ -3092,15 +2841,13 @@ FLUSH TABLES; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 100.00 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 100.00 3 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join ((/* select#3 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` order by `test`.`t2`.`b` limit 2,2) `x`) where `x`.`b` = `test`.`t1`.`a` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from (/* select#3 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` order by `test`.`t2`.`b` limit 2,2) `x` join `test`.`t1` where `x`.`b` = `test`.`t1`.`a` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 7 @@ -3121,12 +2868,10 @@ Sort_scan 1 # query: UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x) # select: SELECT * FROM t1, t2 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x) # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 3 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort FLUSH STATUS; @@ -3134,7 +2879,7 @@ FLUSH TABLES; EXPLAIN EXTENDED UPDATE t1, t2 SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 100.00 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 100.00 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 3 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using filesort # Status of EXPLAIN EXTENDED query @@ -3145,16 +2890,14 @@ FLUSH TABLES; EXPLAIN EXTENDED SELECT * FROM t1, t2 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 100.00 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 100.00 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) 3 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` semi join ((/* select#3 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` order by `test`.`t2`.`b` limit 2,2) `x`) join `test`.`t2` where `x`.`b` = `test`.`t1`.`a` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from (/* select#3 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` order by `test`.`t2`.`b` limit 2,2) `x` join `test`.`t1` join `test`.`t2` where `x`.`b` = `test`.`t1`.`a` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 7 @@ -3174,12 +2917,10 @@ Sort_scan 1 # query: UPDATE t1, (SELECT * FROM t2) y SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x) # select: SELECT * FROM t1, (SELECT * FROM t2) y WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x) # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1, (SELECT * FROM t2) y SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 1 PRIMARY ALL NULL NULL NULL NULL 3 4 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort 2 DERIVED t2 ALL NULL NULL NULL NULL 3 @@ -3188,7 +2929,7 @@ FLUSH TABLES; EXPLAIN EXTENDED UPDATE t1, (SELECT * FROM t2) y SET a = 10 WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 100.00 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 100.00 1 PRIMARY ALL NULL NULL NULL NULL 3 100.00 4 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using filesort 2 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 @@ -3200,16 +2941,14 @@ FLUSH TABLES; EXPLAIN EXTENDED SELECT * FROM t1, (SELECT * FROM t2) y WHERE a IN (SELECT * FROM (SELECT b FROM t2 ORDER BY b LIMIT 2,2) x); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 100.00 FirstMatch(t1) +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 100.00 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) 4 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` semi join ((/* select#4 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` order by `test`.`t2`.`b` limit 2,2) `x`) join `test`.`t2` where `x`.`b` = `test`.`t1`.`a` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from (/* select#4 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` order by `test`.`t2`.`b` limit 2,2) `x` join `test`.`t1` join `test`.`t2` where `x`.`b` = `test`.`t1`.`a` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 4 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 7 @@ -3239,8 +2978,7 @@ JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 ); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DROP TABLE t1, t2, t3; #73 CREATE TABLE t1 (id INT); @@ -3259,8 +2997,6 @@ INSERT INTO t1 VALUES (1), (2), (3), (4), (5); # query: UPDATE t1 SET a=a+1 WHERE a>10 # select: SELECT a t1 FROM t1 WHERE a>10 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET a=a+1 WHERE a>10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using buffer @@ -3282,8 +3018,6 @@ Note 1003 select `test`.`t1`.`a` AS `t1` from `test`.`t1` where `test`.`t1`.`a` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 3 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -3296,8 +3030,6 @@ Handler_read_key 4 # query: UPDATE t1 SET a=a+1 WHERE a>10 ORDER BY a+20 # select: SELECT a t1 FROM t1 WHERE a>10 ORDER BY a+20 # -Warnings: -Warning 1287 ' INTO FROM...' instead EXPLAIN UPDATE t1 SET a=a+1 WHERE a>10 ORDER BY a+20; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort @@ -3319,8 +3051,6 @@ Note 1003 select `test`.`t1`.`a` AS `t1` from `test`.`t1` where `test`.`t1`.`a` # Status of EXPLAIN EXTENDED "equivalent" SELECT query execution Variable_name Value Handler_read_key 3 -Warnings: -Warning 1287 ' INTO FROM...' instead # Status of "equivalent" SELECT query execution: Variable_name Value Handler_read_key 4 @@ -3375,7 +3105,7 @@ CALL p10(); DROP PROCEDURE p10; CALL p9(); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 0 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DROP PROCEDURE p9; CALL p8(); DROP PROCEDURE p8; diff --git a/mysql-test/main/myisam_icp.result b/mysql-test/main/myisam_icp.result index 2bd9ac9ba95..2ffd2d9ad4b 100644 --- a/mysql-test/main/myisam_icp.result +++ b/mysql-test/main/myisam_icp.result @@ -448,9 +448,10 @@ c1 INT NOT NULL, PRIMARY KEY (pk) ); INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1); +insert into t1 select seq,seq from seq_100_to_110; EXPLAIN SELECT pk, c1 FROM t1 WHERE (pk<3 or pk>3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 5 Using where +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 16 Using where SET SESSION optimizer_switch='index_condition_pushdown=off'; SELECT pk, c1 FROM t1 WHERE (pk<3 or pk>3); pk c1 @@ -458,6 +459,17 @@ pk c1 2 7 4 3 5 1 +100 100 +101 101 +102 102 +103 103 +104 104 +105 105 +106 106 +107 107 +108 108 +109 109 +110 110 DROP TABLE t1; set optimizer_switch= @save_optimizer_switch; # @@ -675,7 +687,6 @@ DROP TABLE t1; # CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b)); INSERT INTO t1 VALUES (1,4,'Ill'); -insert into t1 select seq+100,5,seq from seq_1_to_100; CREATE TABLE t2 (a varchar(1024), KEY (a(512))); INSERT INTO t2 VALUES ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w'); @@ -685,8 +696,8 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL # Using where; Using filesort -1 SIMPLE t2 ref a a 515 test.t1.a # Using where +1 SIMPLE t1 system PRIMARY NULL NULL NULL # +1 SIMPLE t2 ref a a 515 const # Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) HAVING t1.c != 5 ORDER BY t1.c; b c @@ -696,8 +707,8 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL # Using where; Using filesort -1 SIMPLE t2 ref a a 515 test.t1.a # Using where +1 SIMPLE t1 system PRIMARY NULL NULL NULL # +1 SIMPLE t2 ref a a 515 const # Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) HAVING t1.c != 5 ORDER BY t1.c; b c @@ -809,6 +820,8 @@ test.t2 analyze status Engine-independent statistics collected test.t2 analyze status Table is already up to date SET @save_optimize_switch=@@optimizer_switch; SET optimizer_switch='materialization=on'; +set @save_optimizer_where_cost=@@optimizer_where_cost; +set @@optimizer_where_cost=1; EXPLAIN SELECT COUNT(*) FROM t1 AS t, t2 WHERE c = g @@ -832,6 +845,7 @@ OR a = 0 AND h < 'z' ); COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; +set @@optimizer_where_cost=@save_optimizer_where_cost; DROP TABLE t1,t2; # check "Handler_pushed" status varuiables CREATE TABLE t1 ( @@ -922,7 +936,7 @@ DROP TABLE t1; # Bug#870046: ICP for a GROUP BY query # CREATE TABLE t1 (a int, b varchar(1), c varchar(1), INDEX idx(b)); -INSERT INTO t1 VALUES (2,'x','x'), (5,'x','y'); +INSERT INTO t1 VALUES (2,'x','x'), (5,'x','y'), (6,'a','b'), (7,'a','b'); SET SESSION optimizer_switch='index_condition_pushdown=off'; EXPLAIN SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a; diff --git a/mysql-test/main/myisam_icp.test b/mysql-test/main/myisam_icp.test index a115d0f7caa..7b4ff23b50e 100644 --- a/mysql-test/main/myisam_icp.test +++ b/mysql-test/main/myisam_icp.test @@ -215,7 +215,7 @@ DROP TABLE t1; --echo # CREATE TABLE t1 (a int, b varchar(1), c varchar(1), INDEX idx(b)); -INSERT INTO t1 VALUES (2,'x','x'), (5,'x','y'); +INSERT INTO t1 VALUES (2,'x','x'), (5,'x','y'), (6,'a','b'), (7,'a','b'); SET SESSION optimizer_switch='index_condition_pushdown=off'; EXPLAIN diff --git a/mysql-test/main/myisam_mrr,32bit.rdiff b/mysql-test/main/myisam_mrr,32bit.rdiff index 746bf48dedd..eda77abbfce 100644 --- a/mysql-test/main/myisam_mrr,32bit.rdiff +++ b/mysql-test/main/myisam_mrr,32bit.rdiff @@ -1,5 +1,5 @@ ---- main/myisam_mrr.result 2019-05-14 15:44:52.232663568 +0530 -+++ main/myisam_mrr.reject 2019-05-14 15:51:37.123563538 +0530 +--- main/myisam_mrr.result ++++ main/myisam_mrr.reject @@ -617,8 +617,8 @@ show status like 'handler_mrr%'; Variable_name Value diff --git a/mysql-test/main/myisam_mrr.result b/mysql-test/main/myisam_mrr.result index b758b2b3258..6bf72e688bc 100644 --- a/mysql-test/main/myisam_mrr.result +++ b/mysql-test/main/myisam_mrr.result @@ -517,7 +517,7 @@ table3.col_varchar_key = table2.col_varchar_nokey AND table3.pk<>0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE table2 ALL col_varchar_key NULL NULL NULL 40 Using where -1 SIMPLE table3 ref PRIMARY,col_varchar_key col_varchar_key 3 test.table2.col_varchar_key 5 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE table3 ALL PRIMARY,col_varchar_key NULL NULL NULL 40 Using where; Using join buffer (flat, BNL join) set join_cache_level= @save_join_cache_level; set join_buffer_size= @save_join_buffer_size; drop table t1; @@ -572,8 +572,7 @@ Handler_mrr_rowid_refills 0 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, filler char(200), key(a)); -insert into t1 -select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D; +insert into t1 select seq, 123, 'filler' from seq_0_to_14999; explain select sum(b) from t1 where a < 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 9 Using index condition; Rowid-ordered scan diff --git a/mysql-test/main/myisam_mrr.test b/mysql-test/main/myisam_mrr.test index 11c9aa64ef1..601844ab385 100644 --- a/mysql-test/main/myisam_mrr.test +++ b/mysql-test/main/myisam_mrr.test @@ -1,6 +1,8 @@ # # MRR/MyISAM tests. # +--source include/have_sequence.inc + --disable_warnings drop table if exists t0, t1, t2, t3; @@ -278,8 +280,7 @@ show status like 'Handler_mrr%'; 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, filler char(200), key(a)); -insert into t1 -select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D; +insert into t1 select seq, 123, 'filler' from seq_0_to_14999; explain select sum(b) from t1 where a < 10; --echo # This should show one MRR scan and no re-fills: diff --git a/mysql-test/main/mysql.result b/mysql-test/main/mysql.result index 0b91b513b17..1792f09d3ac 100644 --- a/mysql-test/main/mysql.result +++ b/mysql-test/main/mysql.result @@ -637,3 +637,6 @@ drop table t1; WARNING: option '--enable-cleartext-plugin' is obsolete. 1 1 +# +# MDEV-30327 Client crashes in print_last_query_cost +# diff --git a/mysql-test/main/mysql.test b/mysql-test/main/mysql.test index 0f41add821a..5aa130f8a4c 100644 --- a/mysql-test/main/mysql.test +++ b/mysql-test/main/mysql.test @@ -709,10 +709,19 @@ drop table t1; --echo # --exec $MYSQL -NHe "select 1 as a" - # # Test obsolete option --enable-cleartext-plugin # This should proceed with a warning # --echo --exec $MYSQL test --enable-cleartext-plugin -e "select 1" + +--echo # +--echo # MDEV-30327 Client crashes in print_last_query_cost +--echo # + +--disable_query_log +--disable_result_log +--exec $MYSQL --show-query-costs --port=$MASTER_MYPORT -e "show tables in mysql like 'foo'" +--enable_result_log +--enable_query_log diff --git a/mysql-test/main/mysql_client_test.result b/mysql-test/main/mysql_client_test.result index dbc1feaa23b..e32053e50f3 100644 --- a/mysql-test/main/mysql_client_test.result +++ b/mysql-test/main/mysql_client_test.result @@ -130,7 +130,7 @@ mysql_stmt_next_result(): 0; field_count: 0 # cat MYSQL_TMP_DIR/test_mdev26145.out.log # ------------------------------------ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def MAX(a) MAX(a) 3 11 0 Y 32768 0 63 +def MAX(a) MAX(a) 3 11 0 Y 49152 0 63 # ------------------------------------ diff --git a/mysql-test/main/mysql_upgrade.test b/mysql-test/main/mysql_upgrade.test index e9caf94d362..8d2a3334d7c 100644 --- a/mysql-test/main/mysql_upgrade.test +++ b/mysql-test/main/mysql_upgrade.test @@ -350,13 +350,23 @@ EOF --echo # MDEV-27279: mariadb_upgrade check-if-upgrade with major version change --echo # +# take 2rd number of version and change to 0. If the 2rd number is already 0, +# change the first number let DATADIR= $MYSQLD_DATADIR; perl; my $ver= $ENV{'MYSQL_SERVER_VERSION'} or die "MYSQL_SERVER_VERSION not set"; my $file= $ENV{'DATADIR'} or die "MYSQLD_DATADIR not set"; - $ver =~ s/^(\d*)\.(\d*).(\d*)(.*)/10.11.2$4/; open(FILE, ">$file/mariadb_upgrade_info") or die "Failed to open $file"; + if ($ver =~ m/(\d*)\.0\.(\d*)(.*)/) + { + my $prev= $1-1; + $ver= $prev . '.0.' . $2 . $3; + } + else + { + $ver =~ s/^(\d*)\.(\d*)\.(\d*)(.*)/$1.0.$3$4/; + } print FILE "$ver\n"; close(FILE); EOF diff --git a/mysql-test/main/mysql_upgrade_noengine.result b/mysql-test/main/mysql_upgrade_noengine.result index 459a1a6ce34..830b574fb9c 100644 --- a/mysql-test/main/mysql_upgrade_noengine.result +++ b/mysql-test/main/mysql_upgrade_noengine.result @@ -11,7 +11,7 @@ table_name t1 table_type BASE TABLE engine BLACKHOLE row_format Fixed -table_rows 0 +table_rows 2 data_length 0 table_comment select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test' and table_name='t2'; @@ -610,7 +610,7 @@ table_name t1 table_type BASE TABLE engine BLACKHOLE row_format Fixed -table_rows 0 +table_rows 2 data_length 0 table_comment select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test' and table_name='t2'; diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 857e11d57ef..458a2ceaad0 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -720,10 +720,32 @@ The following specify which files/extra groups are read (specified before remain max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors (Automatically configured unless set explicitly) + --optimizer-disk-read-cost=# + Cost of reading a block of IO_SIZE (4096) from a disk (in + usec). + --optimizer-disk-read-ratio=# + Chance that we have to do a disk read to find a row or + index entry from the engine cache + (cache_misses/total_cache_requests). 0.0 means that + everything is cached and 1.0 means that nothing is + expected to be in the engine cache. --optimizer-extra-pruning-depth=# If the optimizer needs to enumerate join prefix of this size or larger, then it will try agressively prune away the search space. + --optimizer-index-block-copy-cost=# + Cost of copying a key block from the cache to intern + storage as part of an index scan. + --optimizer-key-compare-cost=# + Cost of checking a key against the end key condition. + --optimizer-key-copy-cost=# + Cost of finding the next key in the engine and copying it + to the SQL layer. + --optimizer-key-lookup-cost=# + Cost for finding a key based on a key value + --optimizer-key-next-find-cost=# + Cost of finding the next key and rowid when using + filters. --optimizer-max-sel-arg-weight=# The maximum weight of the SEL_ARG graph. Set to 0 for no limit @@ -734,6 +756,21 @@ The following specify which files/extra groups are read (specified before remain heuristic, thus perform exhaustive search: 1 - prune plans based on cost and number of retrieved rows eq_ref: 2 - prune also if we find an eq_ref chain + --optimizer-row-copy-cost=# + Cost of copying a row from the engine or the join cache + to the SQL layer. + --optimizer-row-lookup-cost=# + Cost of finding a row based on a rowid or a clustered + key. + --optimizer-row-next-find-cost=# + Cost of finding the next row when scanning the table. + --optimizer-rowid-compare-cost=# + Cost of comparing two rowid's + --optimizer-rowid-copy-cost=# + Cost of copying a rowid + --optimizer-scan-setup-cost=# + Extra cost added to TABLE and INDEX scans to get + optimizer to prefer index lookups. --optimizer-search-depth=# Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query @@ -786,6 +823,10 @@ The following specify which files/extra groups are read (specified before remain the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples + --optimizer-where-cost=# + Cost of checking the row against the WHERE clause. + Increasing this will have the optimizer to prefer plans + with less row combinations. --performance-schema Enable the performance schema. --performance-schema-accounts-size=# @@ -1591,7 +1632,7 @@ gtid-pos-auto-engines gtid-strict-mode FALSE help TRUE histogram-size 254 -histogram-type DOUBLE_PREC_HB +histogram-type JSON_HB host-cache-size 279 idle-readonly-transaction-timeout 0 idle-transaction-timeout 0 @@ -1698,15 +1739,29 @@ old-alter-table DEFAULT old-mode UTF8_IS_UTF8MB3 old-passwords FALSE old-style-user-limits FALSE +optimizer-disk-read-cost 10.24 +optimizer-disk-read-ratio 0.02 optimizer-extra-pruning-depth 8 +optimizer-index-block-copy-cost 0.0356 +optimizer-key-compare-cost 0.011361 +optimizer-key-copy-cost 0.015685 +optimizer-key-lookup-cost 0.435777 +optimizer-key-next-find-cost 0.082347 optimizer-max-sel-arg-weight 32000 optimizer-prune-level 2 +optimizer-row-copy-cost 0.060866 +optimizer-row-lookup-cost 0.130839 +optimizer-row-next-find-cost 0.045916 +optimizer-rowid-compare-cost 0.002653 +optimizer-rowid-copy-cost 0.002653 +optimizer-scan-setup-cost 10 optimizer-search-depth 62 optimizer-selectivity-sampling-limit 100 optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on optimizer-trace optimizer-trace-max-mem-size 1048576 optimizer-use-condition-selectivity 4 +optimizer-where-cost 0.032 performance-schema FALSE performance-schema-accounts-size -1 performance-schema-consumer-events-stages-current FALSE diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test index a73562e4249..ad2307f43c6 100644 --- a/mysql-test/main/mysqld--help.test +++ b/mysql-test/main/mysqld--help.test @@ -29,6 +29,7 @@ perl; collation-server character-set-server log-tc-size table-cache table-open-cache table-open-cache-instances max-connections tls-version version.* password-reuse-check + provider-bzip2 provider-lzma provider-lzo password-reuse-check-interval/; # Plugins which may or may not be there: diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index 44ed94e43c9..2c15a4841eb 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -2822,8 +2822,6 @@ CREATE PROCEDURE bug9056_proc2(OUT a INT) BEGIN select sum(id) from t1 into a; END // -Warnings: -Warning 1287 ' INTO FROM...' instead set sql_mode='ansi'; create procedure `a'b` () select 1; set sql_mode=''; diff --git a/mysql-test/main/named_pipe.result b/mysql-test/main/named_pipe.result index 2baa3471ec9..a0738cdad34 100644 --- a/mysql-test/main/named_pipe.result +++ b/mysql-test/main/named_pipe.result @@ -1,5 +1,6 @@ connect pipe_con,localhost,root,,,,,PIPE; drop table if exists t1,t2,t3,t4; +set @@default_storage_engine="aria"; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -600,6 +601,9 @@ explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +# +# Some test with ORDER BY and limit +# explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort @@ -1289,7 +1293,7 @@ companynr tinyint(2) unsigned zerofill NOT NULL default '00', companyname char(30) NOT NULL default '', PRIMARY KEY (companynr), UNIQUE KEY companyname(companyname) -) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +) ENGINE=aria MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; companynr companyname 00 Unknown @@ -1379,6 +1383,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t2 where fld1=999999; +# +# Test left join optimization +# explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where @@ -1393,15 +1400,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; id select_type table type possible_keys key key_len ref rows Extra @@ -1417,11 +1424,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/null_key.result b/mysql-test/main/null_key.result index 6b9d59c636a..cee3484a304 100644 --- a/mysql-test/main/null_key.result +++ b/mysql-test/main/null_key.result @@ -181,12 +181,12 @@ insert into t2 values (7),(8); explain select * from t2 straight_join t1 where t1.a=t2.a and b is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where -1 SIMPLE t1 ref a,b a 10 test.t2.a,const 2 Using where; Using index +1 SIMPLE t1 ref a,b a 10 test.t2.a,const 1 Using where; Using index drop index b on t1; explain select * from t2,t1 where t1.a=t2.a and b is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where -1 SIMPLE t1 ref a a 10 test.t2.a,const 2 Using where; Using index +1 SIMPLE t1 ref a a 10 test.t2.a,const 1 Using where; Using index select * from t2,t1 where t1.a=t2.a and b is null; a a b 7 7 NULL @@ -258,10 +258,11 @@ PRIMARY KEY (id) ) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); INSERT INTO t1 VALUES (11,5),(12,6),(13,7),(14,8),(15,9); +INSERT INTO t1 VALUES (1000,1000),(1010,1010); INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); explain select id from t1 where uniq_id is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL idx1 NULL NULL NULL 15 Using where +1 SIMPLE t1 ref idx1 idx1 5 const 6 Using index condition explain select id from t1 where uniq_id =1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const idx1 idx1 5 const 1 @@ -285,6 +286,7 @@ id 110 DELETE FROM t1 WHERE uniq_id IS NULL; DELETE FROM t2 WHERE uniq_id IS NULL; +DELETE FROM t1 WHERE id >= 1000; SELECT * FROM t1 ORDER BY uniq_id, id; id uniq_id 3 1 diff --git a/mysql-test/main/null_key.test b/mysql-test/main/null_key.test index 7eabd6d5dc3..65a93022a2e 100644 --- a/mysql-test/main/null_key.test +++ b/mysql-test/main/null_key.test @@ -104,6 +104,7 @@ CREATE TABLE t2 ( INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); INSERT INTO t1 VALUES (11,5),(12,6),(13,7),(14,8),(15,9); +INSERT INTO t1 VALUES (1000,1000),(1010,1010); INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); # # Check IS NULL optimization @@ -122,6 +123,12 @@ select id from t2 where uniq_id is null; # DELETE FROM t1 WHERE uniq_id IS NULL; DELETE FROM t2 WHERE uniq_id IS NULL; + +# +# Delete extra records that were used to force null optimization +# +DELETE FROM t1 WHERE id >= 1000; + # # Select what is left -- notice the difference # diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 2d52392dedb..3571b4ac978 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -118,7 +118,8 @@ select * from v1 { "table": "t1", "table_scan": { "rows": 2, - "cost": 2.004394531 + "read_cost": 0.01028441, + "read_and_compare_cost": 0.01034841 } } ] @@ -126,23 +127,30 @@ select * from v1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 1, - "cost": 2.204394531, + "rows": 2, + "rows_after_filter": 1, + "rows_out": 1, + "cost": 0.01034841, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 1, - "cost": 2.204394531, + "rows_read": 1, + "rows_out": 1, + "cost": 0.01034841, "uses_join_buffering": false } } @@ -150,15 +158,17 @@ select * from v1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 1, - "cost_for_plan": 2.404394531 + "cost_for_plan": 0.01034841 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 1, + "cost": 0.01034841 }, { "substitute_best_equal": { @@ -172,10 +182,13 @@ select * from v1 { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.a = 1" + "attached_condition": "t1.a = 1" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -276,7 +289,8 @@ select * from (select * from t1 where t1.a=1)q { "table": "t1", "table_scan": { "rows": 2, - "cost": 2.004394531 + "read_cost": 0.01028441, + "read_and_compare_cost": 0.01034841 } } ] @@ -284,23 +298,30 @@ select * from (select * from t1 where t1.a=1)q { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 1, - "cost": 2.204394531, + "rows": 2, + "rows_after_filter": 1, + "rows_out": 1, + "cost": 0.01034841, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 1, - "cost": 2.204394531, + "rows_read": 1, + "rows_out": 1, + "cost": 0.01034841, "uses_join_buffering": false } } @@ -308,15 +329,17 @@ select * from (select * from t1 where t1.a=1)q { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 1, - "cost_for_plan": 2.404394531 + "cost_for_plan": 0.01034841 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 1, + "cost": 0.01034841 }, { "substitute_best_equal": { @@ -330,10 +353,13 @@ select * from (select * from t1 where t1.a=1)q { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.a = 1" + "attached_condition": "t1.a = 1" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -439,7 +465,8 @@ select * from v2 { "table": "t1", "table_scan": { "rows": 2, - "cost": 2.004394531 + "read_cost": 0.01028441, + "read_and_compare_cost": 0.01034841 } } ] @@ -447,24 +474,31 @@ select * from v2 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 1, - "cost": 2.204394531, + "rows": 2, + "rows_after_filter": 1, + "rows_out": 1, + "cost": 0.01034841, + "index_only": false, "chosen": true, "use_tmp_table": true } ], "chosen_access_method": { "type": "scan", - "records": 1, - "cost": 2.204394531, + "rows_read": 1, + "rows_out": 1, + "cost": 0.01034841, "uses_join_buffering": false } } @@ -472,16 +506,18 @@ select * from v2 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 1, - "cost_for_plan": 2.404394531, - "cost_for_sorting": 1 + "cost_for_plan": 0.01034841, + "cost_for_sorting": 6.301866e-4 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 1, + "cost": 0.010978597 }, { "substitute_best_equal": { @@ -495,10 +531,13 @@ select * from v2 { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.a = 1" + "attached_condition": "t1.a = 1" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -519,7 +558,8 @@ select * from v2 { "table": "", "table_scan": { "rows": 2, - "cost": 2 + "read_cost": 0.012350033, + "read_and_compare_cost": 0.012418701 } } ] @@ -527,23 +567,30 @@ select * from v2 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 2, - "cost": 2, + "rows": 2, + "rows_after_filter": 2, + "rows_out": 2, + "cost": 0.012418701, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 2, - "cost": 2, + "rows_read": 2, + "rows_out": 2, + "cost": 0.012418701, "uses_join_buffering": false } } @@ -551,15 +598,17 @@ select * from v2 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "", "rows_for_plan": 2, - "cost_for_plan": 2.4 + "cost_for_plan": 0.012418701 } ] }, { - "best_join_order": [""] + "best_join_order": [""], + "rows": 2, + "cost": 0.012418701 }, { "attaching_conditions_to_tables": { @@ -567,10 +616,13 @@ select * from v2 { "attached_conditions_summary": [ { "table": "", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -663,7 +715,8 @@ explain select * from v2 { "table": "t2", "table_scan": { "rows": 10, - "cost": 2.021972656 + "read_cost": 0.01127965, + "read_and_compare_cost": 0.01159965 } } ] @@ -671,23 +724,30 @@ explain select * from v2 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 10, - "cost": 2.021972656, + "rows": 10, + "rows_after_filter": 10, + "rows_out": 10, + "cost": 0.01159965, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 2.021972656, + "rows_read": 10, + "rows_out": 10, + "cost": 0.01159965, "uses_join_buffering": false } } @@ -695,15 +755,17 @@ explain select * from v2 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t2", "rows_for_plan": 10, - "cost_for_plan": 4.021972656 + "cost_for_plan": 0.01159965 } ] }, { - "best_join_order": ["t2"] + "best_join_order": ["t2"], + "rows": 10, + "cost": 0.01159965 }, { "attaching_conditions_to_tables": { @@ -711,10 +773,13 @@ explain select * from v2 { "attached_conditions_summary": [ { "table": "t2", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -786,7 +851,8 @@ explain select * from v1 { "table": "t1", "table_scan": { "rows": 10, - "cost": 2.021972656 + "read_cost": 0.01127965, + "read_and_compare_cost": 0.01159965 } } ] @@ -794,24 +860,31 @@ explain select * from v1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 10, - "cost": 2.021972656, + "rows": 10, + "rows_after_filter": 10, + "rows_out": 10, + "cost": 0.01159965, + "index_only": false, "chosen": true, "use_tmp_table": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 2.021972656, + "rows_read": 10, + "rows_out": 10, + "cost": 0.01159965, "uses_join_buffering": false } } @@ -819,16 +892,18 @@ explain select * from v1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 10, - "cost_for_plan": 4.021972656, - "cost_for_sorting": 10 + "cost_for_plan": 0.01159965, + "cost_for_sorting": 0.006368384 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 10, + "cost": 0.017968034 }, { "attaching_conditions_to_tables": { @@ -836,10 +911,13 @@ explain select * from v1 { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -860,7 +938,8 @@ explain select * from v1 { "table": "", "table_scan": { "rows": 10, - "cost": 10 + "read_cost": 0.012414166, + "read_and_compare_cost": 0.012757506 } } ] @@ -868,23 +947,30 @@ explain select * from v1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 10, - "cost": 10, + "rows": 10, + "rows_after_filter": 10, + "rows_out": 10, + "cost": 0.012757506, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 10, + "rows_read": 10, + "rows_out": 10, + "cost": 0.012757506, "uses_join_buffering": false } } @@ -892,15 +978,17 @@ explain select * from v1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "", "rows_for_plan": 10, - "cost_for_plan": 12 + "cost_for_plan": 0.012757506 } ] }, { - "best_join_order": [""] + "best_join_order": [""], + "rows": 10, + "cost": 0.012757506 }, { "attaching_conditions_to_tables": { @@ -908,10 +996,13 @@ explain select * from v1 { "attached_conditions_summary": [ { "table": "", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -1032,14 +1123,16 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { "table": "t1", "table_scan": { "rows": 100, - "cost": 2.317382812 + "read_cost": 0.0224761, + "read_and_compare_cost": 0.0256761 } }, { "table": "t2", "table_scan": { "rows": 100, - "cost": 2.317382812 + "read_cost": 0.0224761, + "read_and_compare_cost": 0.0256761 } } ] @@ -1047,23 +1140,30 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 100, - "cost": 2.317382812, + "rows": 100, + "rows_after_filter": 100, + "rows_out": 100, + "cost": 0.0256761, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 100, - "cost": 2.317382812, + "rows_read": 100, + "rows_out": 100, + "cost": 0.0256761, "uses_join_buffering": false } } @@ -1071,18 +1171,25 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { { "best_access_path": { "table": "t2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 100, - "cost": 2.317382812, + "rows": 100, + "rows_after_filter": 100, + "rows_out": 100, + "cost": 0.0256761, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 100, - "cost": 2.317382812, + "rows_read": 100, + "rows_out": 100, + "cost": 0.0256761, "uses_join_buffering": false } } @@ -1090,39 +1197,45 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 100, - "cost_for_plan": 22.31738281, + "cost_for_plan": 0.0256761, "rest_of_plan": [ { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "get_costs_for_tables": [ { "best_access_path": { "table": "t2", + "plan_details": { + "record_count": 100 + }, "considered_access_paths": [ { "access_type": "ref", "index": "a", "used_range_estimates": false, "reason": "not available", - "rowid_filter_skipped": "cost_factor <= 0", "rows": 1, - "cost": 200.0585794, + "cost": 0.1821659, "chosen": true }, { - "access_type": "scan", - "resulting_rows": 100, - "cost": 2.317382812, + "access_type": "scan_with_join_cache", + "rows": 100, + "rows_after_filter": 100, + "rows_out": 1, + "cost": 0.9604227, + "index_only": false, "chosen": false } ], "chosen_access_method": { "type": "ref", - "records": 1, - "cost": 200.0585794, + "rows_read": 1, + "rows_out": 1, + "cost": 0.1821659, "uses_join_buffering": false } } @@ -1130,47 +1243,53 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { ] }, { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "table": "t2", "rows_for_plan": 100, - "cost_for_plan": 242.3759623 + "cost_for_plan": 0.207842 } ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t2", "rows_for_plan": 100, - "cost_for_plan": 22.31738281, + "cost_for_plan": 0.0256761, "rest_of_plan": [ { - "plan_prefix": ["t2"], + "plan_prefix": "t2", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 100 + }, "considered_access_paths": [ { "access_type": "ref", "index": "a", "used_range_estimates": false, "reason": "not available", - "rowid_filter_skipped": "cost_factor <= 0", "rows": 1, - "cost": 200.0585794, + "cost": 0.1821659, "chosen": true }, { - "access_type": "scan", - "resulting_rows": 100, - "cost": 2.317382812, + "access_type": "scan_with_join_cache", + "rows": 100, + "rows_after_filter": 100, + "rows_out": 1, + "cost": 0.9604227, + "index_only": false, "chosen": false } ], "chosen_access_method": { "type": "ref", - "records": 1, - "cost": 200.0585794, + "rows_read": 1, + "rows_out": 1, + "cost": 0.1821659, "uses_join_buffering": false } } @@ -1178,20 +1297,22 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { ] }, { - "plan_prefix": ["t2"], + "plan_prefix": "t2", "table": "t1", "rows_for_plan": 100, - "cost_for_plan": 242.3759623, + "cost_for_plan": 0.207842, "pruned_by_cost": true, - "current_cost": 242.3759623, - "best_cost": 242.3759623 + "current_cost": 0.207842, + "best_cost": 0.207842 } ] } ] }, { - "best_join_order": ["t1", "t2"] + "best_join_order": ["t1", "t2"], + "rows": 100, + "cost": 0.207842 }, { "substitute_best_equal": { @@ -1205,14 +1326,17 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.b is not null" + "attached_condition": "t1.b is not null" }, { "table": "t2", - "attached": "t1.a = t2.b + 2" + "attached_condition": "t1.a = t2.b + 2" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -1230,10 +1354,11 @@ drop table t1,t2,t0; # group_by min max optimization # CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a INT NOT NULL, KEY(a)); +insert into t1 select seq, mod(seq,4)+1 from seq_1_to_65536; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status OK +test.t1 analyze status Table is already up to date EXPLAIN SELECT DISTINCT a FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL a 4 NULL 5 Using index for group-by @@ -1272,7 +1397,7 @@ EXPLAIN SELECT DISTINCT a FROM t1 { "range_analysis": { "table_scan": { "rows": 65536, - "cost": 13255.2 + "cost": 10.29477568 }, "potential_range_indexes": [ { @@ -1288,9 +1413,8 @@ EXPLAIN SELECT DISTINCT a FROM t1 { ], "best_covering_index_scan": { "index": "a", - "cost": 13377.39141, - "chosen": false, - "cause": "cost" + "cost": 9.123706862, + "chosen": true }, "group_index_range": { "distinct_query": true, @@ -1299,7 +1423,7 @@ EXPLAIN SELECT DISTINCT a FROM t1 { "index": "a", "covering": true, "rows": 5, - "cost": 6.25 + "cost": 0.004191135 } ] }, @@ -1311,7 +1435,7 @@ EXPLAIN SELECT DISTINCT a FROM t1 { "max_aggregate": false, "distinct_aggregate": false, "rows": 5, - "cost": 6.25, + "cost": 0.004191135, "key_parts_used_for_access": ["a"], "ranges": [], "chosen": true @@ -1325,12 +1449,12 @@ EXPLAIN SELECT DISTINCT a FROM t1 { "max_aggregate": false, "distinct_aggregate": false, "rows": 5, - "cost": 6.25, + "cost": 0.004191135, "key_parts_used_for_access": ["a"], "ranges": [] }, "rows_for_plan": 5, - "cost_for_plan": 6.25, + "cost_for_plan": 0.004191135, "chosen": true } } @@ -1340,23 +1464,29 @@ EXPLAIN SELECT DISTINCT a FROM t1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "index_merge", - "resulting_rows": 5, - "cost": 6.25, + "rows": 5, + "rows_after_filter": 5, + "rows_out": 5, + "cost": 0.004191135, "chosen": true } ], "chosen_access_method": { "type": "index_merge", - "records": 5, - "cost": 6.25, + "rows_read": 5, + "rows_out": 5, + "cost": 0.004191135, "uses_join_buffering": false } } @@ -1364,15 +1494,17 @@ EXPLAIN SELECT DISTINCT a FROM t1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 5, - "cost_for_plan": 7.25 + "cost_for_plan": 0.004191135 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 5, + "cost": 0.004191135 }, { "attaching_conditions_to_tables": { @@ -1380,10 +1512,13 @@ EXPLAIN SELECT DISTINCT a FROM t1 { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -1408,10 +1543,13 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL a 20 NULL 8 Using where; Using index for group-by +1 SIMPLE t1 range NULL a 20 NULL 7 Using where; Using index for group-by +set statement optimizer_scan_setup_cost=0 for EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 20 NULL 7 Using where; Using index select * from information_schema.OPTIMIZER_TRACE; QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES -EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { +set statement optimizer_scan_setup_cost=0 for EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { "steps": [ { "join_preparation": { @@ -1467,7 +1605,7 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { "range_analysis": { "table_scan": { "rows": 7, - "cost": 5.429052734 + "cost": 0.001130435 }, "potential_range_indexes": [ { @@ -1478,8 +1616,9 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { ], "best_covering_index_scan": { "index": "a", - "cost": 2.409226263, - "chosen": true + "cost": 0.001758432, + "chosen": false, + "cause": "cost" }, "setup_range_conditions": [], "analyzing_range_alternatives": { @@ -1495,8 +1634,8 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { "index": "a", "covering": true, "ranges": ["(2,3) <= (b,c) <= (2,3)"], - "rows": 8, - "cost": 2.2 + "rows": 7, + "cost": 0.004425189 } ] }, @@ -1507,54 +1646,61 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { "min_aggregate": true, "max_aggregate": false, "distinct_aggregate": false, - "rows": 8, - "cost": 2.2, + "rows": 7, + "cost": 0.004425189, "key_parts_used_for_access": ["a", "b", "c"], "ranges": ["(2,3) <= (b,c) <= (2,3)"], - "chosen": true - }, - "chosen_range_access_summary": { - "range_access_plan": { - "type": "index_group", - "index": "a", - "min_max_arg": "d", - "min_aggregate": true, - "max_aggregate": false, - "distinct_aggregate": false, - "rows": 8, - "cost": 2.2, - "key_parts_used_for_access": ["a", "b", "c"], - "ranges": ["(2,3) <= (b,c) <= (2,3)"] - }, - "rows_for_plan": 8, - "cost_for_plan": 2.2, - "chosen": true + "chosen": false, + "cause": "cost" } } + }, + { + "selectivity_for_indexes": [], + "selectivity_for_columns": [ + { + "column_name": "b", + "ranges": ["2 <= b <= 2"], + "selectivity_from_histogram": 0.285714286 + }, + { + "column_name": "c", + "ranges": ["3 <= c <= 3"], + "selectivity_from_histogram": 0.285714286 + } + ], + "cond_selectivity": 0.081632653 } ] }, { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { - "access_type": "index_merge", - "resulting_rows": 8, - "cost": 2.2, + "access_type": "scan", + "rows": 7, + "rows_after_filter": 1, + "rows_out": 0.571428573, + "cost": 0.001758432, + "index_only": true, "chosen": true, "use_tmp_table": true } ], "chosen_access_method": { - "type": "index_merge", - "records": 8, - "cost": 2.2, + "type": "scan", + "rows_read": 1, + "rows_out": 0.571428573, + "cost": 0.001758432, "uses_join_buffering": false } } @@ -1562,16 +1708,21 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", - "rows_for_plan": 8, - "cost_for_plan": 3.8, - "cost_for_sorting": 8 + "rows_for_plan": 0.571428573, + "cost_for_plan": 0.001758432, + "pushdown_cond_selectivity": 0.571428573, + "filtered": 8.163265322, + "rows_out": 0.571428573, + "cost_for_sorting": 3.585611e-4 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 0.571428573, + "cost": 0.002116993 }, { "substitute_best_equal": { @@ -1585,7 +1736,32 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.b = 2 and t1.c = 3" + "attached_condition": "t1.b = 2 and t1.c = 3" + } + ] + } + }, + { + "make_join_readinfo": [] + }, + { + "reconsidering_access_paths_for_index_ordering": { + "clause": "GROUP BY", + "table": "t1", + "rows_estimation": 1, + "filesort_cost": 4.579083e-5, + "read_cost": 0.001804223, + "filesort_type": "priority_queue with addon fields", + "fanout": 1, + "possible_keys": [ + { + "index": "a", + "can_resolve_order": true, + "direction": 1, + "rows_to_examine": 7, + "range_scan": false, + "scan_cost": 0.001758432, + "chosen": true } ] } @@ -1673,7 +1849,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { "range_analysis": { "table_scan": { "rows": 16, - "cost": 7.23125 + "cost": 0.01253808 }, "potential_range_indexes": [ { @@ -1684,7 +1860,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { ], "best_covering_index_scan": { "index": "id", - "cost": 4.21171589, + "cost": 0.008002862, "chosen": true }, "setup_range_conditions": [], @@ -1702,7 +1878,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { "covering": true, "ranges": ["(2001-01-04) <= (a)"], "rows": 9, - "cost": 2.35 + "cost": 0.005620843 } ] }, @@ -1714,7 +1890,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { "max_aggregate": true, "distinct_aggregate": false, "rows": 9, - "cost": 2.35, + "cost": 0.005620843, "key_parts_used_for_access": ["id"], "ranges": ["(2001-01-04) <= (a)"], "chosen": true @@ -1728,12 +1904,12 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { "max_aggregate": true, "distinct_aggregate": false, "rows": 9, - "cost": 2.35, + "cost": 0.005620843, "key_parts_used_for_access": ["id"], "ranges": ["(2001-01-04) <= (a)"] }, "rows_for_plan": 9, - "cost_for_plan": 2.35, + "cost_for_plan": 0.005620843, "chosen": true } } @@ -1743,24 +1919,30 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "index_merge", - "resulting_rows": 9, - "cost": 2.35, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.005620843, "chosen": true, "use_tmp_table": true } ], "chosen_access_method": { "type": "index_merge", - "records": 9, - "cost": 2.35, + "rows_read": 9, + "rows_out": 9, + "cost": 0.005620843, "uses_join_buffering": false } } @@ -1768,16 +1950,18 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 9, - "cost_for_plan": 4.15, - "cost_for_sorting": 9 + "cost_for_plan": 0.005620843, + "cost_for_sorting": 0.005728198 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 9, + "cost": 0.011349041 }, { "substitute_best_equal": { @@ -1791,10 +1975,13 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.a >= 20010104e0" + "attached_condition": "t1.a >= 20010104e0" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -1868,7 +2055,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { "range_analysis": { "table_scan": { "rows": 16, - "cost": 7.23125 + "cost": 0.01253808 }, "potential_range_indexes": [ { @@ -1879,7 +2066,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { ], "best_covering_index_scan": { "index": "id", - "cost": 4.21171589, + "cost": 0.008002862, "chosen": true }, "setup_range_conditions": [], @@ -1897,7 +2084,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { "covering": true, "ranges": ["(2001-01-04) <= (a) <= (2001-01-04)"], "rows": 9, - "cost": 2.35 + "cost": 0.005620843 } ] }, @@ -1909,7 +2096,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { "max_aggregate": false, "distinct_aggregate": false, "rows": 9, - "cost": 2.35, + "cost": 0.005620843, "key_parts_used_for_access": ["id", "a"], "ranges": ["(2001-01-04) <= (a) <= (2001-01-04)"], "chosen": true @@ -1923,12 +2110,12 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { "max_aggregate": false, "distinct_aggregate": false, "rows": 9, - "cost": 2.35, + "cost": 0.005620843, "key_parts_used_for_access": ["id", "a"], "ranges": ["(2001-01-04) <= (a) <= (2001-01-04)"] }, "rows_for_plan": 9, - "cost_for_plan": 2.35, + "cost_for_plan": 0.005620843, "chosen": true } } @@ -1938,24 +2125,30 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "index_merge", - "resulting_rows": 9, - "cost": 2.35, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.005620843, "chosen": true, "use_tmp_table": true } ], "chosen_access_method": { "type": "index_merge", - "records": 9, - "cost": 2.35, + "rows_read": 9, + "rows_out": 9, + "cost": 0.005620843, "uses_join_buffering": false } } @@ -1963,16 +2156,18 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 9, - "cost_for_plan": 4.15, - "cost_for_sorting": 9 + "cost_for_plan": 0.005620843, + "cost_for_sorting": 0.005728198 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 9, + "cost": 0.011349041 }, { "substitute_best_equal": { @@ -1986,10 +2181,13 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.a = 20010104e0" + "attached_condition": "t1.a = 20010104e0" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -2006,28 +2204,27 @@ drop table t1; # # Late ORDER BY optimization # -create table ten(a int); -insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -create table one_k(a int primary key); -insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C; create table t1 ( pk int not null, a int, b int, c int, filler char(100), -KEY a_a(c), +KEY c(c), KEY a_c(a,c), KEY a_b(a,b) ); -insert into t1 -select a, a,a,a, 'filler-dataaa' from test.one_k; +insert into t1 select seq, seq,seq,seq, 'filler-dataaa' from seq_0_to_999; update t1 set a=1 where pk between 0 and 180; update t1 set b=2 where pk between 0 and 20; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK +explain select * from t1 where a=1 and b=2 order by c limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a_c,a_b a_b 10 const,const 21 Using where; Using filesort +update t1 set b=2 where pk between 20 and 40; set optimizer_trace='enabled=on'; explain select * from t1 where a=1 and b=2 order by c limit 1; id select_type table type possible_keys key key_len ref rows Extra @@ -2112,11 +2309,11 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "range_analysis": { "table_scan": { "rows": 1000, - "cost": 232.5644531 + "cost": 0.1731718 }, "potential_range_indexes": [ { - "index": "a_a", + "index": "c", "usable": false, "cause": "not applicable" }, @@ -2141,8 +2338,9 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "using_mrr": false, "index_only": false, "rows": 180, - "cost": 216.2943776, - "chosen": true + "cost": 0.223677504, + "chosen": false, + "cause": "cost" }, { "index": "a_b", @@ -2150,8 +2348,8 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "rowid_ordered": true, "using_mrr": false, "index_only": false, - "rows": 21, - "cost": 25.36242739, + "rows": 41, + "cost": 0.051929313, "chosen": true } ], @@ -2168,11 +2366,11 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "range_access_plan": { "type": "range_scan", "index": "a_b", - "rows": 21, + "rows": 41, "ranges": ["(1,2) <= (a,b) <= (1,2)"] }, - "rows_for_plan": 21, - "cost_for_plan": 25.36242739, + "rows_for_plan": 41, + "cost_for_plan": 0.051929313, "chosen": true } } @@ -2182,12 +2380,12 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "rowid_filters": [ { "key": "a_b", - "build_cost": 0.886777098, - "rows": 21 + "build_cost": 6.9153e-4, + "rows": 41 }, { "key": "a_c", - "build_cost": 10.52169992, + "build_cost": 0.0040552, "rows": 180 } ] @@ -2196,7 +2394,7 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "selectivity_for_indexes": [ { "index_name": "a_b", - "selectivity_from_index": 0.021 + "selectivity_from_index": 0.041 } ], "selectivity_for_columns": [ @@ -2211,34 +2409,36 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "selectivity_from_histogram": 0.021 } ], - "cond_selectivity": 0.021 + "cond_selectivity": 0.041 } ] }, { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "ref", "index": "a_c", "used_range_estimates": true, - "rowid_filter_skipped": "worst/max seeks clipping", "rows": 180, - "cost": 180.2743776, + "cost": 0.222922562, "chosen": true }, { "access_type": "ref", "index": "a_b", "used_range_estimates": true, - "rows": 21, - "cost": 21.14242739, + "rows": 41, + "cost": 0.051379171, "chosen": true }, { @@ -2249,8 +2449,9 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { ], "chosen_access_method": { "type": "ref", - "records": 21, - "cost": 21.14242739, + "rows_read": 41, + "rows_out": 41, + "cost": 0.051379171, "uses_join_buffering": false } } @@ -2258,15 +2459,17 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", - "rows_for_plan": 21, - "cost_for_plan": 25.34242739 + "rows_for_plan": 41, + "cost_for_plan": 0.051379171 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 41, + "cost": 0.051379171 }, { "substitute_best_equal": { @@ -2280,36 +2483,40 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } }, + { + "make_join_readinfo": [] + }, { "reconsidering_access_paths_for_index_ordering": { "clause": "ORDER BY", - "fanout": 1, - "read_time": 21.14342739, "table": "t1", - "rows_estimation": 21, + "rows_estimation": 41, + "filesort_cost": 9.387121e-4, + "read_cost": 0.052317883, + "filesort_type": "priority_queue with addon fields", + "fanout": 1, "possible_keys": [ { - "index": "a_a", + "index": "c", "can_resolve_order": true, "direction": 1, - "updated_limit": 47, - "index_scan_time": 47, - "usable": false, - "cause": "cost" + "rows_to_examine": 24, + "range_scan": false, + "scan_cost": 0.030403398, + "chosen": true }, { "index": "a_c", "can_resolve_order": true, "direction": 1, - "updated_limit": 47, - "range_scan_time": 4.331020747, - "index_scan_time": 4.331020747, - "records": 180, + "rows_to_examine": 4.390243902, + "range_scan": true, + "scan_cost": 0.023415994, "chosen": true }, { @@ -2323,13 +2530,9 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { { "table": "t1", "range_analysis": { - "table_scan": { - "rows": 1000, - "cost": 1.79769e308 - }, "potential_range_indexes": [ { - "index": "a_a", + "index": "c", "usable": false, "cause": "not applicable" }, @@ -2354,7 +2557,8 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "using_mrr": false, "index_only": false, "rows": 180, - "cost": 216.2943776, + "cost": 0.223677504, + "cost_with_limit": 0.002574553, "chosen": true } ], @@ -2375,7 +2579,7 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { "ranges": ["(1) <= (a) <= (1)"] }, "rows_for_plan": 180, - "cost_for_plan": 216.2943776, + "cost_for_plan": 0.223677504, "chosen": true } } @@ -2391,7 +2595,7 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { } ] } 0 0 -drop table t1,ten,one_k; +drop table t1; # # TABLE ELIMINATION # @@ -2482,7 +2686,8 @@ select t1.a from t1 left join t2 on t1.a=t2.a { "table": "t1", "table_scan": { "rows": 4, - "cost": 2.006835938 + "read_cost": 0.01053322, + "read_and_compare_cost": 0.01066122 } }, { @@ -2496,23 +2701,30 @@ select t1.a from t1 left join t2 on t1.a=t2.a { { "considered_execution_plans": [ { - "plan_prefix": ["t2"], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 4, - "cost": 2.006835938, + "rows": 4, + "rows_after_filter": 4, + "rows_out": 4, + "cost": 0.01066122, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 4, - "cost": 2.006835938, + "rows_read": 4, + "rows_out": 4, + "cost": 0.01066122, "uses_join_buffering": false } } @@ -2520,15 +2732,17 @@ select t1.a from t1 left join t2 on t1.a=t2.a { ] }, { - "plan_prefix": ["t2"], + "plan_prefix": "", "table": "t1", "rows_for_plan": 4, - "cost_for_plan": 2.806835937 + "cost_for_plan": 0.01066122 } ] }, { - "best_join_order": ["t2", "t1"] + "best_join_order": ["t2", "t1"], + "rows": 4, + "cost": 0.01066122 }, { "substitute_best_equal": { @@ -2536,20 +2750,24 @@ select t1.a from t1 left join t2 on t1.a=t2.a { "resulting_condition": "1" } }, - { - "condition_on_constant_tables": "1", - "computing_condition": [] - }, { "attaching_conditions_to_tables": { - "attached_conditions_computation": [], + "attached_conditions_computation": [ + { + "condition_on_constant_tables": "1", + "computing_condition": [] + } + ], "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -2628,14 +2846,16 @@ explain select * from t1 left join t2 on t2.a=t1.a { "table": "t1", "table_scan": { "rows": 4, - "cost": 2.006835938 + "read_cost": 0.01053322, + "read_and_compare_cost": 0.01066122 } }, { "table": "t2", "table_scan": { "rows": 2, - "cost": 2.004394531 + "read_cost": 0.01028441, + "read_and_compare_cost": 0.01034841 } } ] @@ -2643,23 +2863,30 @@ explain select * from t1 left join t2 on t2.a=t1.a { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 4, - "cost": 2.006835938, + "rows": 4, + "rows_after_filter": 4, + "rows_out": 4, + "cost": 0.01066122, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 4, - "cost": 2.006835938, + "rows_read": 4, + "rows_out": 4, + "cost": 0.01066122, "uses_join_buffering": false } } @@ -2667,36 +2894,39 @@ explain select * from t1 left join t2 on t2.a=t1.a { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 4, - "cost_for_plan": 2.806835937, + "cost_for_plan": 0.01066122, "rest_of_plan": [ { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "get_costs_for_tables": [ { "best_access_path": { "table": "t2", + "plan_details": { + "record_count": 4 + }, "considered_access_paths": [ { "access_type": "eq_ref", "index": "PRIMARY", "rows": 1, - "cost": 4, + "cost": 0.007120904, "chosen": true }, { - "access_type": "scan", - "resulting_rows": 2, - "cost": 8.017578125, - "chosen": false + "type": "scan", + "chosen": false, + "cause": "cost" } ], "chosen_access_method": { "type": "eq_ref", - "records": 1, - "cost": 4, + "rows_read": 1, + "rows_out": 1, + "cost": 0.007120904, "uses_join_buffering": false } } @@ -2704,17 +2934,19 @@ explain select * from t1 left join t2 on t2.a=t1.a { ] }, { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "table": "t2", "rows_for_plan": 4, - "cost_for_plan": 7.606835937 + "cost_for_plan": 0.017782124 } ] } ] }, { - "best_join_order": ["t1", "t2"] + "best_join_order": ["t1", "t2"], + "rows": 4, + "cost": 0.017782124 }, { "substitute_best_equal": { @@ -2729,24 +2961,28 @@ explain select * from t1 left join t2 on t2.a=t1.a { "resulting_condition": "t2.a = t1.a" } }, - { - "condition_on_constant_tables": "1", - "computing_condition": [] - }, { "attaching_conditions_to_tables": { - "attached_conditions_computation": [], + "attached_conditions_computation": [ + { + "condition_on_constant_tables": "1", + "computing_condition": [] + } + ], "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null }, { "table": "t2", - "attached": "trigcond(trigcond(t1.a is not null))" + "attached_condition": "trigcond(trigcond(t1.a is not null))" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -2851,7 +3087,8 @@ explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and "table": "t1", "table_scan": { "rows": 4, - "cost": 2.006835938 + "read_cost": 0.01053322, + "read_and_compare_cost": 0.01066122 } }, { @@ -2871,23 +3108,30 @@ explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and { "considered_execution_plans": [ { - "plan_prefix": ["t3", "t2"], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 4, - "cost": 2.006835938, + "rows": 4, + "rows_after_filter": 4, + "rows_out": 4, + "cost": 0.01066122, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 4, - "cost": 2.006835938, + "rows_read": 4, + "rows_out": 4, + "cost": 0.01066122, "uses_join_buffering": false } } @@ -2895,15 +3139,17 @@ explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and ] }, { - "plan_prefix": ["t3", "t2"], + "plan_prefix": "", "table": "t1", "rows_for_plan": 4, - "cost_for_plan": 2.806835937 + "cost_for_plan": 0.01066122 } ] }, { - "best_join_order": ["t3", "t2", "t1"] + "best_join_order": ["t3", "t2", "t1"], + "rows": 4, + "cost": 0.01066122 }, { "substitute_best_equal": { @@ -2911,20 +3157,24 @@ explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and "resulting_condition": "1" } }, - { - "condition_on_constant_tables": "1", - "computing_condition": [] - }, { "attaching_conditions_to_tables": { - "attached_conditions_computation": [], + "attached_conditions_computation": [ + { + "condition_on_constant_tables": "1", + "computing_condition": [] + } + ], "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -2941,33 +3191,27 @@ drop table t0, t1, t2, t3; # # IN subquery to sem-join is traced # -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 values (0,0),(1,1),(2,2); -create table t2 as select * from t1; -create table t11(a int, b int); -create table t10 (pk int, a int); -insert into t10 select a,a from t0; -create table t12 like t10; -insert into t12 select * from t10; -analyze table t1,t10; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status OK -test.t10 analyze status Engine-independent statistics collected -test.t10 analyze status OK +insert into t1 select seq,seq from seq_0_to_3; +create table t2 (p int, a int); +insert into t2 select seq,seq from seq_1_to_10; set optimizer_trace='enabled=on'; -explain extended select * from t1 where a in (select pk from t10); +explain extended select * from t1 where a in (select p from t2); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t10 ALL NULL NULL NULL NULL 10 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 10 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t10`) where 1 +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`p` = `test`.`t1`.`a` +insert into t2 select seq,seq from seq_10_to_100; +explain extended select * from t1 where a in (select p from t2); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 101 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`p` = `test`.`t1`.`a` select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE; QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES -explain extended select * from t1 where a in (select pk from t10) { +explain extended select * from t1 where a in (select p from t2) { "steps": [ { "join_preparation": { @@ -2986,13 +3230,13 @@ explain extended select * from t1 where a in (select pk from t10) { } }, { - "expanded_query": "/* select#2 */ select t10.pk from t10" + "expanded_query": "/* select#2 */ select t2.p from t2" } ] } }, { - "expanded_query": "/* select#1 */ select t1.a AS a,t1.b AS b from t1 where t1.a in (/* select#2 */ select t10.pk from t10)" + "expanded_query": "/* select#1 */ select t1.a AS a,t1.b AS b from t1 where t1.a in (/* select#2 */ select t2.p from t2)" } ] } @@ -3021,19 +3265,19 @@ explain extended select * from t1 where a in (select pk from t10) { { "condition_processing": { "condition": "WHERE", - "original_condition": "1 and t1.a = t10.pk", + "original_condition": "1 and t1.a = t2.p", "steps": [ { "transformation": "equality_propagation", - "resulting_condition": "1 and multiple equal(t1.a, t10.pk)" + "resulting_condition": "1 and multiple equal(t1.a, t2.p)" }, { "transformation": "constant_propagation", - "resulting_condition": "1 and multiple equal(t1.a, t10.pk)" + "resulting_condition": "1 and multiple equal(t1.a, t2.p)" }, { "transformation": "trivial_condition_removal", - "resulting_condition": "multiple equal(t1.a, t10.pk)" + "resulting_condition": "multiple equal(t1.a, t2.p)" } ] } @@ -3047,7 +3291,7 @@ explain extended select * from t1 where a in (select pk from t10) { "depends_on_map_bits": [] }, { - "table": "t10", + "table": "t2", "row_may_be_null": false, "map_bit": 1, "depends_on_map_bits": [] @@ -3062,15 +3306,17 @@ explain extended select * from t1 where a in (select pk from t10) { { "table": "t1", "table_scan": { - "rows": 3, - "cost": 2.006591797 + "rows": 4, + "read_cost": 0.01053322, + "read_and_compare_cost": 0.01066122 } }, { - "table": "t10", + "table": "t2", "table_scan": { - "rows": 10, - "cost": 2.021972656 + "rows": 101, + "read_cost": 0.022600505, + "read_and_compare_cost": 0.025832505 } } ] @@ -3086,23 +3332,30 @@ explain extended select * from t1 where a in (select pk from t10) { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { - "table": "t10", + "table": "t2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 10, - "cost": 2.021972656, + "rows": 101, + "rows_after_filter": 101, + "rows_out": 101, + "cost": 0.025832505, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 2.021972656, + "rows_read": 101, + "rows_out": 101, + "cost": 0.025832505, "uses_join_buffering": false } } @@ -3110,10 +3363,10 @@ explain extended select * from t1 where a in (select pk from t10) { ] }, { - "plan_prefix": [], - "table": "t10", - "rows_for_plan": 10, - "cost_for_plan": 4.021972656 + "plan_prefix": "", + "table": "t2", + "rows_for_plan": 101, + "cost_for_plan": 0.025832505 } ] } @@ -3123,42 +3376,56 @@ explain extended select * from t1 where a in (select pk from t10) { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.006591797, + "rows": 4, + "rows_after_filter": 4, + "rows_out": 4, + "cost": 0.01066122, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.006591797, + "rows_read": 4, + "rows_out": 4, + "cost": 0.01066122, "uses_join_buffering": false } } }, { "best_access_path": { - "table": "t10", + "table": "t2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 10, - "cost": 2.021972656, + "rows": 101, + "rows_after_filter": 101, + "rows_out": 101, + "cost": 0.025832505, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 2.021972656, + "rows_read": 101, + "rows_out": 101, + "cost": 0.025832505, "uses_join_buffering": false } } @@ -3166,30 +3433,37 @@ explain extended select * from t1 where a in (select pk from t10) { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", - "rows_for_plan": 3, - "cost_for_plan": 2.606591797, + "rows_for_plan": 4, + "cost_for_plan": 0.01066122, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "get_costs_for_tables": [ { "best_access_path": { - "table": "t10", + "table": "t2", + "plan_details": { + "record_count": 4 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 10, - "cost": 2.021972656, + "access_type": "scan_with_join_cache", + "rows": 101, + "rows_after_filter": 101, + "rows_out": 101, + "cost": 0.063593833, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 2.021972656, + "rows_read": 101, + "rows_out": 101, + "cost": 0.063593833, "uses_join_buffering": true } } @@ -3197,38 +3471,47 @@ explain extended select * from t1 where a in (select pk from t10) { ] }, { - "plan_prefix": ["t1"], - "table": "t10", - "rows_for_plan": 30, - "cost_for_plan": 10.62856445, + "plan_prefix": "t1", + "table": "t2", + "rows_for_plan": 404, + "cost_for_plan": 0.074255053, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 3, - "read_time": 10.62856445 + "rows": 4, + "cost": 0.074255053 }, { "strategy": "SJ-Materialization", - "records": 3, - "read_time": 5.278564453 + "rows": 4, + "cost": 0.078768645 }, { "strategy": "DuplicateWeedout", - "records": 3, - "read_time": 27.12856445 + "prefix_row_count": 4, + "tmp_table_rows": 1, + "sj_inner_fanout": 101, + "rows": 4, + "dups_cost": 0.074255053, + "write_cost": 0.02564388, + "full_lookup_cost": 0.06503188, + "total_cost": 0.164930813 }, { - "chosen_strategy": "SJ-Materialization" + "chosen_strategy": "FirstMatch" } - ] + ], + "sj_rows_out": 1, + "sj_rows_for_plan": 4, + "sj_filtered": 0.99009901 } ] }, { - "plan_prefix": [], - "table": "t10", - "rows_for_plan": 10, - "cost_for_plan": 4.021972656, + "plan_prefix": "", + "table": "t2", + "rows_for_plan": 101, + "cost_for_plan": 0.025832505, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } @@ -3237,46 +3520,67 @@ explain extended select * from t1 where a in (select pk from t10) { { "fix_semijoin_strategies_for_picked_join_order": [ { - "semi_join_strategy": "SJ-Materialization", + "semi_join_strategy": "FirstMatch", "join_order": [ { - "table": "t10" + "table": "t2", + "best_access_path": { + "table": "t2", + "plan_details": { + "record_count": 4 + }, + "considered_access_paths": [ + { + "access_type": "scan", + "rows": 101, + "rows_after_filter": 101, + "rows_out": 101, + "cost": 0.10333002, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 101, + "rows_out": 101, + "cost": 0.10333002, + "uses_join_buffering": false + } + } } ] } ] }, { - "best_join_order": ["t1", ""] + "best_join_order": ["t1", "t2"], + "rows": 4, + "cost": 0.074255053 }, { "substitute_best_equal": { "condition": "WHERE", - "resulting_condition": "1" + "resulting_condition": "t2.p = t1.a" } }, - { - "condition_on_constant_tables": "1", - "computing_condition": [] - }, { "attaching_conditions_to_tables": { "attached_conditions_computation": [], "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null }, { - "table": "t10", - "attached": null - }, - { - "table": "", - "attached": null + "table": "t2", + "attached_condition": "t2.p = t1.a" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -3289,12 +3593,10 @@ explain extended select * from t1 where a in (select pk from t10) { } ] } 0 0 -drop table t0,t1,t11,t10,t12,t2; +drop table t1,t2; # # Selectivities for columns and indexes. # -create table t0 (a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 ( pk int, a int, @@ -3302,7 +3604,7 @@ b int, key pk(pk), key pk_a(pk,a), key pk_a_b(pk,a,b)); -insert into t1 select a,a,a from t0; +insert into t1 select seq,seq,seq from seq_0_to_9; ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a,b) INDEXES (); Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected @@ -3416,7 +3718,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "range_analysis": { "table_scan": { "rows": 10, - "cost": 6.031738281 + "cost": 0.01159965 }, "potential_range_indexes": [ { @@ -3437,7 +3739,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { ], "best_covering_index_scan": { "index": "pk_a_b", - "cost": 3.010739566, + "cost": 0.007173242, "chosen": true }, "setup_range_conditions": [], @@ -3450,7 +3752,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.345585794, + "cost": 0.002574553, "chosen": true }, { @@ -3460,7 +3762,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.345829876, + "cost": 0.002574553, "chosen": false, "cause": "cost" }, @@ -3471,7 +3773,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "using_mrr": false, "index_only": true, "rows": 1, - "cost": 0.346073957, + "cost": 0.001478954, "chosen": true } ], @@ -3479,10 +3781,10 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "intersecting_indexes": [ { "index": "pk", - "index_scan_cost": 1.000585794, - "cumulated_index_scan_cost": 1.000585794, - "disk_sweep_cost": 0.90078125, - "cumulative_total_cost": 1.901367044, + "index_scan_cost": 0.000806227, + "cumulated_index_scan_cost": 0.000806227, + "disk_sweep_cost": 0.001143284, + "cumulative_total_cost": 0.001949511, "usable": true, "matching_rows_now": 1, "intersect_covering_with_this_index": false, @@ -3520,7 +3822,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "ranges": ["(2,5,1) <= (pk,a,b) <= (2,5,1)"] }, "rows_for_plan": 1, - "cost_for_plan": 0.346073957, + "cost_for_plan": 0.001478954, "chosen": true } } @@ -3530,17 +3832,17 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "rowid_filters": [ { "key": "pk", - "build_cost": 0.130585794, + "build_cost": 0.000002653, "rows": 1 }, { "key": "pk_a", - "build_cost": 0.130829876, + "build_cost": 0.000002653, "rows": 1 }, { "key": "pk_a_b", - "build_cost": 0.131073957, + "build_cost": 0.000002653, "rows": 1 } ] @@ -3571,18 +3873,21 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "ref", "index": "pk", "used_range_estimates": true, "rows": 1, - "cost": 1.125585794, + "cost": 0.002024411, "chosen": true }, { @@ -3590,7 +3895,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "index": "pk_a", "used_range_estimates": true, "rows": 1, - "cost": 1.125829876, + "cost": 0.002024411, "chosen": false, "cause": "cost" }, @@ -3599,7 +3904,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "index": "pk_a_b", "used_range_estimates": true, "rows": 1, - "cost": 0.126073957, + "cost": 0.000928812, "chosen": true }, { @@ -3610,8 +3915,9 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { ], "chosen_access_method": { "type": "ref", - "records": 1, - "cost": 0.126073957, + "rows_read": 1, + "rows_out": 1, + "cost": 0.000928812, "uses_join_buffering": false } } @@ -3619,15 +3925,17 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 1, - "cost_for_plan": 0.326073957 + "cost_for_plan": 0.000928812 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 1, + "cost": 0.000928812 }, { "substitute_best_equal": { @@ -3641,10 +3949,13 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -3659,7 +3970,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { } 0 0 set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set @@use_stat_tables= @save_use_stat_tables; -drop table t0,t1; +drop table t1; set optimizer_trace="enabled=off"; # # Tests added to show that sub-statements are not traced @@ -3680,8 +3991,6 @@ declare a int default 0; select count(*) from t2 into a; return a; end| -Warnings: -Warning 1287 ' INTO FROM...' instead set optimizer_trace='enabled=on'; select f1(a) from t1; f1(a) @@ -3723,7 +4032,8 @@ select f1(a) from t1 { "table": "t1", "table_scan": { "rows": 4, - "cost": 2.006835938 + "read_cost": 0.01053322, + "read_and_compare_cost": 0.01066122 } } ] @@ -3731,23 +4041,30 @@ select f1(a) from t1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 4, - "cost": 2.006835938, + "rows": 4, + "rows_after_filter": 4, + "rows_out": 4, + "cost": 0.01066122, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 4, - "cost": 2.006835938, + "rows_read": 4, + "rows_out": 4, + "cost": 0.01066122, "uses_join_buffering": false } } @@ -3755,15 +4072,17 @@ select f1(a) from t1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 4, - "cost_for_plan": 2.806835937 + "cost_for_plan": 0.01066122 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 4, + "cost": 0.01066122 }, { "attaching_conditions_to_tables": { @@ -3771,10 +4090,13 @@ select f1(a) from t1 { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -3827,7 +4149,8 @@ select f2(a) from t1 { "table": "t1", "table_scan": { "rows": 4, - "cost": 2.006835938 + "read_cost": 0.01053322, + "read_and_compare_cost": 0.01066122 } } ] @@ -3835,23 +4158,30 @@ select f2(a) from t1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 4, - "cost": 2.006835938, + "rows": 4, + "rows_after_filter": 4, + "rows_out": 4, + "cost": 0.01066122, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 4, - "cost": 2.006835938, + "rows_read": 4, + "rows_out": 4, + "cost": 0.01066122, "uses_join_buffering": false } } @@ -3859,15 +4189,17 @@ select f2(a) from t1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 4, - "cost_for_plan": 2.806835937 + "cost_for_plan": 0.01066122 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 4, + "cost": 0.01066122 }, { "attaching_conditions_to_tables": { @@ -3875,10 +4207,13 @@ select f2(a) from t1 { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -3908,7 +4243,7 @@ a 2 select length(trace) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; length(trace) -2360 +2819 set optimizer_trace_max_mem_size=100; select * from t1; a @@ -3922,7 +4257,7 @@ select * from t1 { "join_preparation": { "select_id": 1, "steps": [ - 2260 0 + 2719 0 set optimizer_trace_max_mem_size=0; select * from t1; a @@ -3930,7 +4265,7 @@ a 2 select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE; QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES -select * from t1 2360 0 +select * from t1 2819 0 drop table t1; set optimizer_trace='enabled=off'; set @@optimizer_trace_max_mem_size= @save_optimizer_trace_max_mem_size; @@ -3955,7 +4290,7 @@ explain delete from t0 where t0.a<3 { "range_analysis": { "table_scan": { "rows": 10, - "cost": 6.021972656 + "cost": 0.01159965 }, "potential_range_indexes": [ { @@ -3974,7 +4309,7 @@ explain delete from t0 where t0.a<3 { "using_mrr": false, "index_only": false, "rows": 3, - "cost": 3.746757383, + "cost": 0.005042291, "chosen": true } ], @@ -3992,7 +4327,7 @@ explain delete from t0 where t0.a<3 { "ranges": ["(NULL) < (a) < (3)"] }, "rows_for_plan": 3, - "cost_for_plan": 3.746757383, + "cost_for_plan": 0.005042291, "chosen": true } } @@ -4095,7 +4430,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "range_analysis": { "table_scan": { "rows": 10, - "cost": 6.021972656 + "cost": 0.01159965 }, "potential_range_indexes": [ { @@ -4106,7 +4441,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { ], "best_covering_index_scan": { "index": "a", - "cost": 3.005857945, + "cost": 0.007173242, "chosen": true }, "setup_range_conditions": [], @@ -4119,7 +4454,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "using_mrr": false, "index_only": true, "rows": 3, - "cost": 0.746757383, + "cost": 0.001755494, "chosen": true } ], @@ -4140,7 +4475,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "ranges": ["(NULL) < (a) < (3)"] }, "rows_for_plan": 3, - "cost_for_plan": 0.746757383, + "cost_for_plan": 0.001755494, "chosen": true } } @@ -4160,7 +4495,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "range_analysis": { "table_scan": { "rows": 10, - "cost": 6.021972656 + "cost": 0.01159965 }, "potential_range_indexes": [ { @@ -4171,7 +4506,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { ], "best_covering_index_scan": { "index": "a", - "cost": 3.005857945, + "cost": 0.007173242, "chosen": true }, "setup_range_conditions": [], @@ -4184,7 +4519,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "using_mrr": false, "index_only": true, "rows": 3, - "cost": 0.746757383, + "cost": 0.001755494, "chosen": true } ], @@ -4205,7 +4540,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "ranges": ["(NULL) < (a) < (3)"] }, "rows_for_plan": 3, - "cost_for_plan": 0.746757383, + "cost_for_plan": 0.001755494, "chosen": true } } @@ -4225,23 +4560,30 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t0", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "range", - "resulting_rows": 3, - "cost": 0.746757383, + "range_index": "a", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.001755494, "chosen": true } ], "chosen_access_method": { "type": "range", - "records": 3, - "cost": 0.746757383, + "rows_read": 3, + "rows_out": 3, + "cost": 0.001755494, "uses_join_buffering": false } } @@ -4249,18 +4591,25 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "range", - "resulting_rows": 3, - "cost": 0.746757383, + "range_index": "a", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.001755494, "chosen": true } ], "chosen_access_method": { "type": "range", - "records": 3, - "cost": 0.746757383, + "rows_read": 3, + "rows_out": 3, + "cost": 0.001755494, "uses_join_buffering": false } } @@ -4268,26 +4617,28 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t0", "rows_for_plan": 3, - "cost_for_plan": 1.346757383, + "cost_for_plan": 0.001755494, "rest_of_plan": [ { - "plan_prefix": ["t0"], + "plan_prefix": "t0", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { "access_type": "ref", "index": "a", "used_range_estimates": false, "reason": "not better than ref estimates", - "rowid_filter_skipped": "cost_factor <= 0", "rows": 1, - "cost": 3.001757383, + "cost": 0.002376836, "chosen": true }, { @@ -4298,8 +4649,9 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { ], "chosen_access_method": { "type": "ref", - "records": 1, - "cost": 3.001757383, + "rows_read": 1, + "rows_out": 1, + "cost": 0.002376836, "uses_join_buffering": false } } @@ -4307,25 +4659,28 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { ] }, { - "plan_prefix": ["t0"], + "plan_prefix": "t0", "table": "t1", "rows_for_plan": 3, - "cost_for_plan": 4.948514767 + "cost_for_plan": 0.00413233 } ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 3, - "cost_for_plan": 1.346757383, + "cost_for_plan": 0.001755494, "rest_of_plan": [ { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "get_costs_for_tables": [ { "best_access_path": { "table": "t0", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { "access_type": "ref", @@ -4333,9 +4688,8 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "rec_per_key_stats_missing": true, "used_range_estimates": false, "reason": "not better than ref estimates", - "rowid_filter_skipped": "worst/max seeks clipping", - "rows": 2, - "cost": 3.003514767, + "rows": 1.166666667, + "cost": 0.002392836, "chosen": true }, { @@ -4346,8 +4700,9 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { ], "chosen_access_method": { "type": "ref", - "records": 2, - "cost": 3.003514767, + "rows_read": 1.166666667, + "rows_out": 1.166666667, + "cost": 0.002392836, "uses_join_buffering": false } } @@ -4355,20 +4710,22 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { ] }, { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "table": "t0", - "rows_for_plan": 6, - "cost_for_plan": 5.55027215, + "rows_for_plan": 3.5, + "cost_for_plan": 0.00414833, "pruned_by_cost": true, - "current_cost": 5.55027215, - "best_cost": 4.948514767 + "current_cost": 0.00414833, + "best_cost": 0.00413233 } ] } ] }, { - "best_join_order": ["t0", "t1"] + "best_join_order": ["t0", "t1"], + "rows": 3, + "cost": 0.00413233 }, { "substitute_best_equal": { @@ -4382,14 +4739,17 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "attached_conditions_summary": [ { "table": "t0", - "attached": "t0.a < 3 and t0.a is not null" + "attached_condition": "t0.a < 3 and t0.a is not null" }, { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -4477,7 +4837,8 @@ explain select * from (select rand() from t1)q { "table": "t1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } } ] @@ -4485,23 +4846,30 @@ explain select * from (select rand() from t1)q { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -4509,15 +4877,17 @@ explain select * from (select rand() from t1)q { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953 + "cost_for_plan": 0.010504815 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 3, + "cost": 0.010504815 }, { "attaching_conditions_to_tables": { @@ -4525,10 +4895,13 @@ explain select * from (select rand() from t1)q { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -4549,7 +4922,8 @@ explain select * from (select rand() from t1)q { "table": "", "table_scan": { "rows": 3, - "cost": 3 + "read_cost": 0.01235805, + "read_and_compare_cost": 0.012461052 } } ] @@ -4557,23 +4931,30 @@ explain select * from (select rand() from t1)q { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 3, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.012461052, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 3, + "rows_read": 3, + "rows_out": 3, + "cost": 0.012461052, "uses_join_buffering": false } } @@ -4581,15 +4962,17 @@ explain select * from (select rand() from t1)q { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "", "rows_for_plan": 3, - "cost_for_plan": 3.6 + "cost_for_plan": 0.012461052 } ] }, { - "best_join_order": [""] + "best_join_order": [""], + "rows": 3, + "cost": 0.012461052 }, { "attaching_conditions_to_tables": { @@ -4597,10 +4980,13 @@ explain select * from (select rand() from t1)q { "attached_conditions_summary": [ { "table": "", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -4741,21 +5127,24 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ "table": "t1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } }, { "table": "t_inner_1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } }, { "table": "t_inner_2", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } } ] @@ -4771,23 +5160,30 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -4795,18 +5191,25 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -4814,29 +5217,36 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "rest_of_plan": [ { - "plan_prefix": ["t_inner_1"], + "plan_prefix": "t_inner_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.011523207, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.011523207, "uses_join_buffering": true } } @@ -4844,18 +5254,18 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ ] }, { - "plan_prefix": ["t_inner_1"], + "plan_prefix": "t_inner_1", "table": "t_inner_2", "rows_for_plan": 9, - "cost_for_plan": 6.410253906 + "cost_for_plan": 0.022028022 } ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_2", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "pruned_by_heuristic": true } ] @@ -4866,23 +5276,30 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -4890,18 +5307,25 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -4909,18 +5333,25 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -4928,30 +5359,37 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.011523207, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.011523207, "uses_join_buffering": true } } @@ -4959,18 +5397,25 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.011523207, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.011523207, "uses_join_buffering": true } } @@ -4978,30 +5423,37 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ ] }, { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "table": "t_inner_1", "rows_for_plan": 9, - "cost_for_plan": 6.410253906, + "cost_for_plan": 0.022028022, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t1", "t_inner_1"], + "plan_prefix": "t1,t_inner_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.015203373, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.015203373, "uses_join_buffering": true } } @@ -5009,56 +5461,65 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ ] }, { - "plan_prefix": ["t1", "t_inner_1"], + "plan_prefix": "t1,t_inner_1", "table": "t_inner_2", "rows_for_plan": 27, - "cost_for_plan": 13.81538086, + "cost_for_plan": 0.037231395, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 3, - "read_time": 33.86665039 + "rows": 3, + "cost": 0.136562595 }, { "strategy": "SJ-Materialization", - "records": 3, - "read_time": 7.215380859 + "rows": 3, + "cost": 0.059588485 }, { "strategy": "DuplicateWeedout", - "records": 3, - "read_time": 18.31538086 + "prefix_row_count": 3, + "tmp_table_rows": 1, + "sj_inner_fanout": 9, + "rows": 3, + "dups_cost": 0.037231395, + "write_cost": 0.02548291, + "full_lookup_cost": 0.00434619, + "total_cost": 0.067060495 }, { "chosen_strategy": "SJ-Materialization" } - ] + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 3, + "sj_filtered": 11.11111111 } ] }, { - "plan_prefix": ["t1"], + "plan_prefix": "t1", "table": "t_inner_2", "rows_for_plan": 9, - "cost_for_plan": 6.410253906, + "cost_for_plan": 0.022028022, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_2", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } @@ -5080,7 +5541,9 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ ] }, { - "best_join_order": ["t1", ""] + "best_join_order": ["t1", ""], + "rows": 3, + "cost": 0.059588485 }, { "substitute_best_equal": { @@ -5088,32 +5551,36 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ "resulting_condition": "1" } }, - { - "condition_on_constant_tables": "1", - "computing_condition": [] - }, { "attaching_conditions_to_tables": { - "attached_conditions_computation": [], + "attached_conditions_computation": [ + { + "condition_on_constant_tables": "1", + "computing_condition": [] + } + ], "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null }, { "table": "t_inner_1", - "attached": null + "attached_condition": null }, { "table": "t_inner_2", - "attached": null + "attached_condition": null }, { "table": "", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -5295,42 +5762,48 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "table": "t_outer_1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } }, { "table": "t_outer_2", "table_scan": { "rows": 9, - "cost": 2.015380859 + "read_cost": 0.011155245, + "read_and_compare_cost": 0.011443245 } }, { "table": "t_inner_2", "table_scan": { "rows": 9, - "cost": 2.015380859 + "read_cost": 0.011155245, + "read_and_compare_cost": 0.011443245 } }, { "table": "t_inner_1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } }, { "table": "t_inner_3", "table_scan": { "rows": 9, - "cost": 2.015380859 + "read_cost": 0.011155245, + "read_and_compare_cost": 0.011443245 } }, { "table": "t_inner_4", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } } ] @@ -5353,23 +5826,30 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t_outer_1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -5377,18 +5857,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -5396,18 +5883,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.011443245, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.011443245, "uses_join_buffering": false } } @@ -5415,18 +5909,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.011443245, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.011443245, "uses_join_buffering": false } } @@ -5434,18 +5935,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -5453,18 +5961,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.011443245, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.011443245, "uses_join_buffering": false } } @@ -5472,30 +5987,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_outer_1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.011523207, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.011523207, "uses_join_buffering": true } } @@ -5503,18 +6025,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.014133225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.014133225, "uses_join_buffering": true } } @@ -5522,18 +6051,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.014133225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.014133225, "uses_join_buffering": true } } @@ -5541,18 +6077,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.011523207, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.011523207, "uses_join_buffering": true } } @@ -5560,18 +6103,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.014133225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.014133225, "uses_join_buffering": true } } @@ -5579,30 +6129,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_outer_2", "rows_for_plan": 27, - "cost_for_plan": 10.02050781, + "cost_for_plan": 0.02463804, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.050443503, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.050443503, "uses_join_buffering": true } } @@ -5610,18 +6167,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.024600489, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.024600489, "uses_join_buffering": true } } @@ -5629,18 +6193,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.024600489, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.024600489, "uses_join_buffering": true } } @@ -5648,18 +6219,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.050443503, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.050443503, "uses_join_buffering": true } } @@ -5667,30 +6245,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "table": "t_inner_1", "rows_for_plan": 81, - "cost_for_plan": 28.22563477, + "cost_for_plan": 0.049238529, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_outer_2", "t_inner_1"], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.172815333, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.172815333, "uses_join_buffering": true } } @@ -5698,18 +6283,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.067582275, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.067582275, "uses_join_buffering": true } } @@ -5717,18 +6309,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.172815333, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.172815333, "uses_join_buffering": true } } @@ -5736,49 +6335,60 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2", "t_inner_1"], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1", "table": "t_inner_2", "rows_for_plan": 729, - "cost_for_plan": 176.0410156, + "cost_for_plan": 0.222053862, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 27, - "read_time": 389.4047852 + "rows": 27, + "cost": 1.23517089 }, { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 289.4410156 + "prefix_row_count": 27, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.222053862, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.368747182 }, { "chosen_strategy": "DuplicateWeedout" } ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704, "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.034460781, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.034460781, "uses_join_buffering": true } } @@ -5786,18 +6396,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.080024379, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.080024379, "uses_join_buffering": true } } @@ -5805,41 +6422,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2", "table": "t_inner_4", "rows_for_plan": 81, - "cost_for_plan": 307.6461426, + "cost_for_plan": 0.403207963, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.261557961, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.261557961, "uses_join_buffering": true } } @@ -5847,79 +6460,79 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2,t_inner_4", "table": "t_inner_3", "rows_for_plan": 729, - "cost_for_plan": 455.4615234, + "cost_for_plan": 0.664765924, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 27, - "read_time": 668.825293 + "rows": 27, + "cost": 1.579280032 }, { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 568.8615234 + "prefix_row_count": 27, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.664765924, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.811459244 }, { "chosen_strategy": "DuplicateWeedout" } - ] + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704 } ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2", "table": "t_inner_3", "rows_for_plan": 243, - "cost_for_plan": 340.0563965, + "cost_for_plan": 0.448771561, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2", "t_inner_1"], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1", "table": "t_inner_4", "rows_for_plan": 243, - "cost_for_plan": 78.83076172, + "cost_for_plan": 0.116820804, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 243 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, "uses_join_buffering": true } } @@ -5927,18 +6540,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 243 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, "uses_join_buffering": true } } @@ -5946,41 +6566,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_4", "table": "t_inner_2", "rows_for_plan": 2187, - "cost_for_plan": 518.2461426, + "cost_for_plan": 0.745494255, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_4", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_4,t_inner_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 2187 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 6.764540577, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 6.764540577, "uses_join_buffering": true } } @@ -5988,113 +6604,118 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_4", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_4,t_inner_2", "table": "t_inner_3", "rows_for_plan": 19683, - "cost_for_plan": 4456.861523, + "cost_for_plan": 7.510034832, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 27, - "read_time": 9562.749707 + "rows": 27, + "cost": 28.96624341 }, { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 7413.361523 + "prefix_row_count": 27, + "tmp_table_rows": 1, + "sj_inner_fanout": 729, + "rows": 27, + "dups_cost": 7.510034832, + "write_cost": 0.02934619, + "full_lookup_cost": 3.16837251, + "total_cost": 10.70775353 }, { "chosen_strategy": "FirstMatch" } ], + "sj_rows_out": 0.012345679, + "sj_rows_for_plan": 27, + "sj_filtered": 0.137174211, "pruned_by_cost": true, - "current_cost": 9562.749707, - "best_cost": 568.8615234 + "current_cost": 28.96624341, + "best_cost": 0.811459244 } ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_4", "table": "t_inner_3", "rows_for_plan": 2187, - "cost_for_plan": 518.2461426, + "cost_for_plan": 0.745494255, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2", "t_inner_1"], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1", "table": "t_inner_3", "rows_for_plan": 729, - "cost_for_plan": 176.0410156, + "cost_for_plan": 0.222053862, "semijoin_strategy_choice": [], "pruned_by_heuristic": "min_read_time" } ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "table": "t_inner_2", "rows_for_plan": 243, - "cost_for_plan": 60.63588867, + "cost_for_plan": 0.075081543, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "table": "t_inner_4", "rows_for_plan": 81, - "cost_for_plan": 28.22563477, + "cost_for_plan": 0.049238529, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "table": "t_inner_3", "rows_for_plan": 243, - "cost_for_plan": 60.63588867, + "cost_for_plan": 0.075081543, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_inner_1", "rows_for_plan": 9, - "cost_for_plan": 6.410253906, + "cost_for_plan": 0.022028022, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.024443331, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.024443331, "uses_join_buffering": true } } @@ -6102,18 +6723,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.024443331, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.024443331, "uses_join_buffering": true } } @@ -6121,18 +6749,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.015203373, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.015203373, "uses_join_buffering": true } } @@ -6140,18 +6775,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.024443331, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.024443331, "uses_join_buffering": true } } @@ -6159,30 +6801,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "table": "t_outer_2", "rows_for_plan": 81, - "cost_for_plan": 24.62563477, + "cost_for_plan": 0.046471353, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.172815333, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.172815333, "uses_join_buffering": true } } @@ -6190,18 +6839,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.067582275, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.067582275, "uses_join_buffering": true } } @@ -6209,18 +6865,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.172815333, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.172815333, "uses_join_buffering": true } } @@ -6228,44 +6891,55 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2", "table": "t_inner_2", "rows_for_plan": 729, - "cost_for_plan": 172.4410156, + "cost_for_plan": 0.219286686, "semijoin_strategy_choice": [ { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 285.8410156 + "prefix_row_count": 3, + "tmp_table_rows": 9, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.219286686, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.365980006 }, { "chosen_strategy": "DuplicateWeedout" } ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704, "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.034460781, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.034460781, "uses_join_buffering": true } } @@ -6273,18 +6947,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.080024379, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.080024379, "uses_join_buffering": true } } @@ -6292,41 +6973,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_2", "table": "t_inner_4", "rows_for_plan": 81, - "cost_for_plan": 304.0461426, + "cost_for_plan": 0.400440787, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_2,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.261557961, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.261557961, "uses_join_buffering": true } } @@ -6334,79 +7011,79 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_2,t_inner_4", "table": "t_inner_3", "rows_for_plan": 729, - "cost_for_plan": 451.8615234, + "cost_for_plan": 0.661998748, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 27, - "read_time": 665.225293 + "rows": 27, + "cost": 1.576512856 }, { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 565.2615234 + "prefix_row_count": 27, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.661998748, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.808692068 }, { "chosen_strategy": "DuplicateWeedout" } - ] + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704 } ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_2", "table": "t_inner_3", "rows_for_plan": 243, - "cost_for_plan": 336.4563965, + "cost_for_plan": 0.446004385, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2", "table": "t_inner_4", "rows_for_plan": 243, - "cost_for_plan": 75.23076172, + "cost_for_plan": 0.114053628, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 243 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, "uses_join_buffering": true } } @@ -6414,18 +7091,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 243 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, "uses_join_buffering": true } } @@ -6433,41 +7117,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4", "table": "t_inner_2", "rows_for_plan": 2187, - "cost_for_plan": 514.6461426, + "cost_for_plan": 0.742727079, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_4", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4,t_inner_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 2187 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 6.764540577, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 6.764540577, "uses_join_buffering": true } } @@ -6475,96 +7155,110 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_4", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4,t_inner_2", "table": "t_inner_3", "rows_for_plan": 19683, - "cost_for_plan": 4453.261523, + "cost_for_plan": 7.507267656, "semijoin_strategy_choice": [ { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 7409.761523 + "prefix_row_count": 3, + "tmp_table_rows": 9, + "sj_inner_fanout": 729, + "rows": 27, + "dups_cost": 7.507267656, + "write_cost": 0.02934619, + "full_lookup_cost": 3.16837251, + "total_cost": 10.70498636 }, { "chosen_strategy": "DuplicateWeedout" } ], + "sj_rows_out": 0.012345679, + "sj_rows_for_plan": 27, + "sj_filtered": 0.137174211, "pruned_by_cost": true, - "current_cost": 7409.761523, - "best_cost": 565.2615234 + "current_cost": 10.70498636, + "best_cost": 0.808692068 } ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_outer_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4", "table": "t_inner_3", "rows_for_plan": 2187, - "cost_for_plan": 514.6461426, + "cost_for_plan": 0.742727079, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2", "table": "t_inner_3", "rows_for_plan": 729, - "cost_for_plan": 172.4410156, + "cost_for_plan": 0.219286686, "semijoin_strategy_choice": [], "pruned_by_heuristic": "min_read_time" } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "table": "t_inner_2", "rows_for_plan": 81, - "cost_for_plan": 24.62563477, + "cost_for_plan": 0.046471353, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 3, - "read_time": 44.75893555 + "rows": 3, + "cost": 0.145008465 }, { "strategy": "DuplicateWeedout", - "records": 3, - "read_time": 37.22563477 + "prefix_row_count": 3, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 3, + "dups_cost": 0.046471353, + "write_cost": 0.02548291, + "full_lookup_cost": 0.01303857, + "total_cost": 0.084992833 }, { "chosen_strategy": "DuplicateWeedout" } ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 3, + "sj_filtered": 3.703703704, "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.017419989, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.017419989, "uses_join_buffering": true } } @@ -6572,18 +7266,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.012618795, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.012618795, "uses_join_buffering": true } } @@ -6591,18 +7292,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.017419989, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.017419989, "uses_join_buffering": true } } @@ -6610,35 +7318,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2", "table": "t_outer_2", "rows_for_plan": 27, - "cost_for_plan": 44.64101563, + "cost_for_plan": 0.102412822, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.034460781, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.034460781, "uses_join_buffering": true } } @@ -6646,18 +7356,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.080024379, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.080024379, "uses_join_buffering": true } } @@ -6665,41 +7382,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2", "table": "t_inner_4", "rows_for_plan": 81, - "cost_for_plan": 62.84614258, + "cost_for_plan": 0.136873603, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_outer_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.261557961, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.261557961, "uses_join_buffering": true } } @@ -6707,79 +7420,79 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_outer_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2,t_inner_4", "table": "t_inner_3", "rows_for_plan": 729, - "cost_for_plan": 210.6615234, + "cost_for_plan": 0.398431564, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 27, - "read_time": 424.025293 + "rows": 27, + "cost": 1.312945672 }, { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 324.0615234 + "prefix_row_count": 27, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.398431564, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.545124884 }, { "chosen_strategy": "DuplicateWeedout" } - ] + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704 } ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2", "table": "t_inner_3", "rows_for_plan": 243, - "cost_for_plan": 95.25639648, + "cost_for_plan": 0.182437201, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2", "table": "t_inner_4", "rows_for_plan": 9, - "cost_for_plan": 41.03076172, + "cost_for_plan": 0.097611628, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.034303623, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.034303623, "uses_join_buffering": true } } @@ -6787,18 +7500,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.034303623, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.034303623, "uses_join_buffering": true } } @@ -6806,41 +7526,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4", "table": "t_outer_2", "rows_for_plan": 81, - "cost_for_plan": 59.24614258, + "cost_for_plan": 0.131915251, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_inner_4", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4,t_outer_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.261557961, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.261557961, "uses_join_buffering": true } } @@ -6848,79 +7564,84 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_inner_4", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4,t_outer_2", "table": "t_inner_3", "rows_for_plan": 729, - "cost_for_plan": 207.0615234, + "cost_for_plan": 0.393473212, "semijoin_strategy_choice": [ { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 320.4615234 + "prefix_row_count": 3, + "tmp_table_rows": 9, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.393473212, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.540166532 }, { "chosen_strategy": "DuplicateWeedout" } - ] + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704 } ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4", "table": "t_inner_3", "rows_for_plan": 81, - "cost_for_plan": 59.24614258, + "cost_for_plan": 0.131915251, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2", "table": "t_inner_3", "rows_for_plan": 27, - "cost_for_plan": 44.64101563, + "cost_for_plan": 0.102412822, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "table": "t_inner_4", "rows_for_plan": 27, - "cost_for_plan": 13.81538086, + "cost_for_plan": 0.037231395, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_4"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.065233941, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.065233941, "uses_join_buffering": true } } @@ -6928,18 +7649,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.065233941, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.065233941, "uses_join_buffering": true } } @@ -6947,18 +7675,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.065233941, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.065233941, "uses_join_buffering": true } } @@ -6966,35 +7701,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_4"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4", "table": "t_outer_2", "rows_for_plan": 243, - "cost_for_plan": 64.43076172, + "cost_for_plan": 0.102465336, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_4", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4,t_outer_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 243 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, "uses_join_buffering": true } } @@ -7002,18 +7739,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 243 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, "uses_join_buffering": true } } @@ -7021,128 +7765,118 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_4", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4,t_outer_2", "table": "t_inner_2", "rows_for_plan": 2187, - "cost_for_plan": 503.8461426, + "cost_for_plan": 0.731138787, "semijoin_strategy_choice": [], "pruned_by_cost": true, - "current_cost": 503.8461426, - "best_cost": 320.4615234 + "current_cost": 0.731138787, + "best_cost": 0.540166532 }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_4", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4,t_outer_2", "table": "t_inner_3", "rows_for_plan": 2187, - "cost_for_plan": 503.8461426, + "cost_for_plan": 0.731138787, "semijoin_strategy_choice": [], "pruned_by_cost": true, - "current_cost": 503.8461426, - "best_cost": 320.4615234 + "current_cost": 0.731138787, + "best_cost": 0.540166532 } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_4"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4", "table": "t_inner_2", "rows_for_plan": 243, - "cost_for_plan": 64.43076172, + "cost_for_plan": 0.102465336, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_4"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4", "table": "t_inner_3", "rows_for_plan": 243, - "cost_for_plan": 64.43076172, + "cost_for_plan": 0.102465336, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "table": "t_inner_3", "rows_for_plan": 81, - "cost_for_plan": 24.62563477, + "cost_for_plan": 0.046471353, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_inner_2", "rows_for_plan": 27, - "cost_for_plan": 10.02050781, + "cost_for_plan": 0.02463804, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_inner_4", "rows_for_plan": 9, - "cost_for_plan": 6.410253906, + "cost_for_plan": 0.022028022, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_inner_3", "rows_for_plan": 27, - "cost_for_plan": 10.02050781, + "cost_for_plan": 0.02463804, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_outer_2", "rows_for_plan": 9, - "cost_for_plan": 3.815380859, + "cost_for_plan": 0.011443245, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_2", "rows_for_plan": 9, - "cost_for_plan": 3.815380859, + "cost_for_plan": 0.011443245, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_4", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_3", "rows_for_plan": 9, - "cost_for_plan": 3.815380859, + "cost_for_plan": 0.011443245, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } @@ -7166,7 +7900,9 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "t_inner_4", "t_outer_2", "t_inner_3" - ] + ], + "rows": 27, + "cost": 0.540166532 }, { "substitute_best_equal": { @@ -7180,30 +7916,33 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "attached_conditions_summary": [ { "table": "t_outer_1", - "attached": null + "attached_condition": null }, { "table": "t_inner_1", - "attached": "t_inner_1.a = t_outer_1.a" + "attached_condition": "t_inner_1.a = t_outer_1.a" }, { "table": "t_inner_2", - "attached": null + "attached_condition": null }, { "table": "t_inner_4", - "attached": null + "attached_condition": null }, { "table": "t_outer_2", - "attached": null + "attached_condition": null }, { "table": "t_inner_3", - "attached": "t_inner_3.a = t_outer_2.a" + "attached_condition": "t_inner_3.a = t_outer_2.a" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -7221,8 +7960,8 @@ explain select * from t1 t_outer_1,t2 t_outer_2 where t_outer_1.a in (select t_ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t_outer_1 ALL NULL NULL NULL NULL 3 -1 PRIMARY t_outer_2 ALL NULL NULL NULL NULL 9 Using join buffer (flat, BNL join) 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t_outer_2 ALL NULL NULL NULL NULL 9 Using join buffer (flat, BNL join) 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t_inner_1 ALL NULL NULL NULL NULL 3 2 MATERIALIZED t_inner_2 ALL NULL NULL NULL NULL 9 Using join buffer (flat, BNL join) @@ -7386,42 +8125,48 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "table": "t_outer_1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } }, { "table": "t_outer_2", "table_scan": { "rows": 9, - "cost": 2.015380859 + "read_cost": 0.011155245, + "read_and_compare_cost": 0.011443245 } }, { "table": "t_inner_2", "table_scan": { "rows": 9, - "cost": 2.015380859 + "read_cost": 0.011155245, + "read_and_compare_cost": 0.011443245 } }, { "table": "t_inner_1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } }, { "table": "t_inner_3", "table_scan": { "rows": 9, - "cost": 2.015380859 + "read_cost": 0.011155245, + "read_and_compare_cost": 0.011443245 } }, { "table": "t_inner_4", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } } ] @@ -7442,23 +8187,30 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -7466,18 +8218,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.011443245, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.011443245, "uses_join_buffering": false } } @@ -7485,29 +8244,36 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "rest_of_plan": [ { - "plan_prefix": ["t_inner_1"], + "plan_prefix": "t_inner_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.014133225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.014133225, "uses_join_buffering": true } } @@ -7515,18 +8281,18 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_inner_1"], + "plan_prefix": "t_inner_1", "table": "t_inner_2", "rows_for_plan": 27, - "cost_for_plan": 10.02050781 + "cost_for_plan": 0.02463804 } ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_2", "rows_for_plan": 9, - "cost_for_plan": 3.815380859, + "cost_for_plan": 0.011443245, "pruned_by_heuristic": true } ] @@ -7534,23 +8300,30 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -7558,18 +8331,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.011443245, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.011443245, "uses_join_buffering": false } } @@ -7577,29 +8357,36 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_4", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "rest_of_plan": [ { - "plan_prefix": ["t_inner_4"], + "plan_prefix": "t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.014133225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.014133225, "uses_join_buffering": true } } @@ -7607,18 +8394,18 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_inner_4"], + "plan_prefix": "t_inner_4", "table": "t_inner_3", "rows_for_plan": 27, - "cost_for_plan": 10.02050781 + "cost_for_plan": 0.02463804 } ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_3", "rows_for_plan": 9, - "cost_for_plan": 3.815380859, + "cost_for_plan": 0.011443245, "pruned_by_heuristic": true } ] @@ -7629,23 +8416,30 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t_outer_1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -7653,18 +8447,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -7672,18 +8473,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.011443245, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.011443245, "uses_join_buffering": false } } @@ -7691,18 +8499,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.011443245, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.011443245, "uses_join_buffering": false } } @@ -7710,18 +8525,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -7729,18 +8551,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.011443245, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.011443245, "uses_join_buffering": false } } @@ -7748,30 +8577,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_outer_1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.011523207, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.011523207, "uses_join_buffering": true } } @@ -7779,18 +8615,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.014133225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.014133225, "uses_join_buffering": true } } @@ -7798,18 +8641,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.014133225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.014133225, "uses_join_buffering": true } } @@ -7817,18 +8667,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.011523207, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.011523207, "uses_join_buffering": true } } @@ -7836,18 +8693,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 3 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.014133225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.014133225, "uses_join_buffering": true } } @@ -7855,30 +8719,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_outer_2", "rows_for_plan": 27, - "cost_for_plan": 10.02050781, + "cost_for_plan": 0.02463804, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.050443503, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.050443503, "uses_join_buffering": true } } @@ -7886,18 +8757,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_1", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.024600489, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.024600489, "uses_join_buffering": true } } @@ -7905,18 +8783,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.024600489, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.024600489, "uses_join_buffering": true } } @@ -7924,18 +8809,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.050443503, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.050443503, "uses_join_buffering": true } } @@ -7943,30 +8835,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "table": "t_inner_1", "rows_for_plan": 81, - "cost_for_plan": 28.22563477, + "cost_for_plan": 0.049238529, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_outer_2", "t_inner_1"], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.172815333, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.172815333, "uses_join_buffering": true } } @@ -7974,18 +8873,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.067582275, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.067582275, "uses_join_buffering": true } } @@ -7993,18 +8899,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.172815333, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.172815333, "uses_join_buffering": true } } @@ -8012,54 +8925,65 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2", "t_inner_1"], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1", "table": "t_inner_2", "rows_for_plan": 729, - "cost_for_plan": 176.0410156, + "cost_for_plan": 0.222053862, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 27, - "read_time": 389.4047852 + "rows": 27, + "cost": 1.23517089 }, { "strategy": "SJ-Materialization", - "records": 27, - "read_time": 16.74101562 + "rows": 27, + "cost": 0.083958496 }, { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 289.4410156 + "prefix_row_count": 27, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.222053862, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.368747182 }, { "chosen_strategy": "SJ-Materialization" } ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704, "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.034460781, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.034460781, "uses_join_buffering": true } } @@ -8067,18 +8991,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.080024379, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.080024379, "uses_join_buffering": true } } @@ -8086,41 +9017,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2", "table": "t_inner_4", "rows_for_plan": 81, - "cost_for_plan": 34.94614258, + "cost_for_plan": 0.118419277, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.261557961, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.261557961, "uses_join_buffering": true } } @@ -8128,135 +9055,132 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2,t_inner_4", "table": "t_inner_3", "rows_for_plan": 729, - "cost_for_plan": 182.7615234, + "cost_for_plan": 0.379977238, "semijoin_strategy_choice": [ { "strategy": "FirstMatch", - "records": 27, - "read_time": 396.125293 + "rows": 27, + "cost": 1.294491346 }, { "strategy": "SJ-Materialization", - "records": 27, - "read_time": 23.46152344 + "rows": 27, + "cost": 0.143278952 }, { "strategy": "DuplicateWeedout", - "records": 27, - "read_time": 296.1615234 + "prefix_row_count": 27, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.379977238, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.526670558 }, { "chosen_strategy": "SJ-Materialization" } - ] + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704 } ] }, { - "plan_prefix": [ - "t_outer_1", - "t_outer_2", - "t_inner_1", - "t_inner_2" - ], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1,t_inner_2", "table": "t_inner_3", "rows_for_plan": 243, - "cost_for_plan": 67.35639648, + "cost_for_plan": 0.163982875, "semijoin_strategy_choice": [], "pruned_by_cost": true, - "current_cost": 67.35639648, - "best_cost": 23.46152344 + "current_cost": 0.163982875, + "best_cost": 0.143278952 } ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2", "t_inner_1"], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1", "table": "t_inner_4", "rows_for_plan": 243, - "cost_for_plan": 78.83076172, + "cost_for_plan": 0.116820804, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 78.83076172, - "best_cost": 23.46152344 + "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1", "t_outer_2", "t_inner_1"], + "plan_prefix": "t_outer_1,t_outer_2,t_inner_1", "table": "t_inner_3", "rows_for_plan": 729, - "cost_for_plan": 176.0410156, + "cost_for_plan": 0.222053862, "semijoin_strategy_choice": [], "pruned_by_cost": true, - "current_cost": 176.0410156, - "best_cost": 23.46152344 + "current_cost": 0.222053862, + "best_cost": 0.143278952 } ] }, { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "table": "t_inner_2", "rows_for_plan": 243, - "cost_for_plan": 60.63588867, + "cost_for_plan": 0.075081543, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 60.63588867, - "best_cost": 23.46152344 + "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "table": "t_inner_4", "rows_for_plan": 81, - "cost_for_plan": 28.22563477, + "cost_for_plan": 0.049238529, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 28.22563477, - "best_cost": 23.46152344 + "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1", "t_outer_2"], + "plan_prefix": "t_outer_1,t_outer_2", "table": "t_inner_3", "rows_for_plan": 243, - "cost_for_plan": 60.63588867, + "cost_for_plan": 0.075081543, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 60.63588867, - "best_cost": 23.46152344 + "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_inner_1", "rows_for_plan": 9, - "cost_for_plan": 6.410253906, + "cost_for_plan": 0.022028022, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_2", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.024443331, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.024443331, "uses_join_buffering": true } } @@ -8264,18 +9188,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.024443331, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.024443331, "uses_join_buffering": true } } @@ -8283,18 +9214,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.015203373, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.015203373, "uses_join_buffering": true } } @@ -8302,18 +9240,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.024443331, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.024443331, "uses_join_buffering": true } } @@ -8321,59 +9266,37 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "table": "t_outer_2", "rows_for_plan": 81, - "cost_for_plan": 24.62563477, + "cost_for_plan": 0.046471353, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 24.62563477, - "best_cost": 23.46152344 - }, - { - "plan_prefix": ["t_outer_1", "t_inner_1"], - "table": "t_inner_2", - "rows_for_plan": 81, - "cost_for_plan": 24.62563477, - "semijoin_strategy_choice": [ - { - "strategy": "FirstMatch", - "records": 3, - "read_time": 44.75893555 - }, - { - "strategy": "SJ-Materialization", - "records": 3, - "read_time": 8.125634766 - }, - { - "strategy": "DuplicateWeedout", - "records": 3, - "read_time": 37.22563477 - }, - { - "chosen_strategy": "SJ-Materialization" - } - ], "rest_of_plan": [ { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2", "get_costs_for_tables": [ { "best_access_path": { - "table": "t_outer_2", + "table": "t_inner_2", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.172815333, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.172815333, "uses_join_buffering": true } } @@ -8381,18 +9304,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.067582275, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.067582275, "uses_join_buffering": true } } @@ -8400,18 +9330,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.172815333, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.172815333, "uses_join_buffering": true } } @@ -8419,35 +9356,351 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_2"], - "table": "t_outer_2", - "rows_for_plan": 27, - "cost_for_plan": 15.54101562, + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2", + "table": "t_inner_2", + "rows_for_plan": 729, + "cost_for_plan": 0.219286686, + "semijoin_strategy_choice": [ + { + "strategy": "DuplicateWeedout", + "prefix_row_count": 3, + "tmp_table_rows": 9, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.219286686, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.365980006 + }, + { + "chosen_strategy": "DuplicateWeedout" + } + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704, + "pruned_by_cost": true, + "current_cost": 0.365980006, + "best_cost": 0.143278952 + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2", + "table": "t_inner_4", + "rows_for_plan": 243, + "cost_for_plan": 0.114053628, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_outer_2" + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t_inner_2", + "plan_details": { + "record_count": 243 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, + "uses_join_buffering": true + } + } + }, + { + "best_access_path": { + "table": "t_inner_3", + "plan_details": { + "record_count": 243 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, + "uses_join_buffering": true + } + } + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4", + "table": "t_inner_2", + "rows_for_plan": 2187, + "cost_for_plan": 0.742727079, + "semijoin_strategy_choice": [], + "pruned_by_cost": true, + "current_cost": 0.742727079, + "best_cost": 0.143278952 + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4", + "table": "t_inner_3", + "rows_for_plan": 2187, + "cost_for_plan": 0.742727079, + "semijoin_strategy_choice": [ + { + "strategy": "SJ-Materialization", + "rows": 81, + "cost": 0.116338225 + }, + { + "chosen_strategy": "SJ-Materialization" + } ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 81, + "sj_filtered": 3.703703704, + "rest_of_plan": [ + { + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4,t_inner_3", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t_inner_2", + "plan_details": { + "record_count": 81 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.261557961, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.261557961, + "uses_join_buffering": true + } + } + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2,t_inner_4,t_inner_3", + "table": "t_inner_2", + "rows_for_plan": 729, + "cost_for_plan": 0.377896186, + "semijoin_strategy_choice": [ + { + "strategy": "DuplicateWeedout", + "prefix_row_count": 3, + "tmp_table_rows": 9, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 1.00428504, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 1.15097836 + }, + { + "chosen_strategy": "DuplicateWeedout" + } + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704, + "pruned_by_cost": true, + "current_cost": 1.15097836, + "best_cost": 0.143278952 + } + ] + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_outer_2", + "table": "t_inner_3", + "rows_for_plan": 729, + "cost_for_plan": 0.219286686, + "semijoin_strategy_choice": [], + "pruned_by_cost": true, + "current_cost": 0.219286686, + "best_cost": 0.143278952 + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1", + "table": "t_inner_2", + "rows_for_plan": 81, + "cost_for_plan": 0.046471353, + "semijoin_strategy_choice": [ + { + "strategy": "FirstMatch", + "rows": 3, + "cost": 0.145008465 + }, + { + "strategy": "SJ-Materialization", + "rows": 3, + "cost": 0.065137975 + }, + { + "strategy": "DuplicateWeedout", + "prefix_row_count": 3, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 3, + "dups_cost": 0.046471353, + "write_cost": 0.02548291, + "full_lookup_cost": 0.01303857, + "total_cost": 0.084992833 + }, + { + "chosen_strategy": "SJ-Materialization" + } + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 3, + "sj_filtered": 3.703703704, + "rest_of_plan": [ + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t_outer_2", + "plan_details": { + "record_count": 3 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.017419989, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.017419989, + "uses_join_buffering": true + } + } + }, + { + "best_access_path": { + "table": "t_inner_4", + "plan_details": { + "record_count": 3 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.012618795, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 3, + "rows_out": 3, + "cost": 0.012618795, + "uses_join_buffering": true + } + } + }, + { + "best_access_path": { + "table": "t_inner_3", + "plan_details": { + "record_count": 3 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.017419989, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.017419989, + "uses_join_buffering": true + } + } + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2", + "table": "t_outer_2", + "rows_for_plan": 27, + "cost_for_plan": 0.082557964, + "semijoin_strategy_choice": [], + "rest_of_plan": [ + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2", "get_costs_for_tables": [ { "best_access_path": { "table": "t_inner_4", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "access_type": "scan_with_join_cache", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.034460781, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.034460781, "uses_join_buffering": true } } @@ -8455,18 +9708,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.080024379, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.080024379, "uses_join_buffering": true } } @@ -8474,67 +9734,124 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2", "table": "t_inner_4", "rows_for_plan": 81, - "cost_for_plan": 33.74614258, + "cost_for_plan": 0.117018745, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 33.74614258, - "best_cost": 23.46152344 + "rest_of_plan": [ + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2,t_inner_4", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.261557961, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.261557961, + "uses_join_buffering": true + } + } + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2,t_inner_4", + "table": "t_inner_3", + "rows_for_plan": 729, + "cost_for_plan": 0.378576706, + "semijoin_strategy_choice": [ + { + "strategy": "FirstMatch", + "rows": 27, + "cost": 1.293090814 + }, + { + "strategy": "SJ-Materialization", + "rows": 27, + "cost": 0.14187842 + }, + { + "strategy": "DuplicateWeedout", + "prefix_row_count": 27, + "tmp_table_rows": 1, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.378576706, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.525270026 + }, + { + "chosen_strategy": "SJ-Materialization" + } + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704 + } + ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_outer_2" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_outer_2", "table": "t_inner_3", "rows_for_plan": 243, - "cost_for_plan": 66.15639648, + "cost_for_plan": 0.162582343, "semijoin_strategy_choice": [], "pruned_by_cost": true, - "current_cost": 66.15639648, - "best_cost": 23.46152344 + "current_cost": 0.162582343, + "best_cost": 0.14187842 } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2", "table": "t_inner_4", "rows_for_plan": 9, - "cost_for_plan": 11.93076172, + "cost_for_plan": 0.07775677, "semijoin_strategy_choice": [], "rest_of_plan": [ { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4", "get_costs_for_tables": [ { "best_access_path": { "table": "t_outer_2", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.034303623, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.034303623, "uses_join_buffering": true } } @@ -8542,18 +9859,25 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_access_path": { "table": "t_inner_3", + "plan_details": { + "record_count": 9 + }, "considered_access_paths": [ { - "access_type": "scan", - "resulting_rows": 9, - "cost": 2.015380859, + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.034303623, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 9, - "cost": 2.015380859, + "rows_read": 9, + "rows_out": 9, + "cost": 0.034303623, "uses_join_buffering": true } } @@ -8561,130 +9885,360 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4", "table": "t_outer_2", "rows_for_plan": 81, - "cost_for_plan": 30.14614258, + "cost_for_plan": 0.112060393, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 30.14614258, - "best_cost": 23.46152344 + "rest_of_plan": [ + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4,t_outer_2", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t_inner_3", + "plan_details": { + "record_count": 81 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.261557961, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.261557961, + "uses_join_buffering": true + } + } + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4,t_outer_2", + "table": "t_inner_3", + "rows_for_plan": 729, + "cost_for_plan": 0.373618354, + "semijoin_strategy_choice": [ + { + "strategy": "DuplicateWeedout", + "prefix_row_count": 3, + "tmp_table_rows": 9, + "sj_inner_fanout": 27, + "rows": 27, + "dups_cost": 0.373618354, + "write_cost": 0.02934619, + "full_lookup_cost": 0.11734713, + "total_cost": 0.520311674 + }, + { + "chosen_strategy": "DuplicateWeedout" + } + ], + "sj_rows_out": 0.333333333, + "sj_rows_for_plan": 27, + "sj_filtered": 3.703703704, + "pruned_by_cost": true, + "current_cost": 0.520311674, + "best_cost": 0.14187842 + } + ] }, { - "plan_prefix": [ - "t_outer_1", - "t_inner_1", - "t_inner_2", - "t_inner_4" - ], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2,t_inner_4", "table": "t_inner_3", "rows_for_plan": 81, - "cost_for_plan": 30.14614258, + "cost_for_plan": 0.112060393, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 30.14614258, - "best_cost": 23.46152344 + "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1", "t_inner_2"], + "plan_prefix": "t_outer_1,t_inner_1,t_inner_2", "table": "t_inner_3", "rows_for_plan": 27, - "cost_for_plan": 15.54101562, + "cost_for_plan": 0.082557964, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "table": "t_inner_4", "rows_for_plan": 27, - "cost_for_plan": 13.81538086, + "cost_for_plan": 0.037231395, "semijoin_strategy_choice": [], - "pruned_by_heuristic": true + "rest_of_plan": [ + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t_outer_2", + "plan_details": { + "record_count": 27 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.065233941, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.065233941, + "uses_join_buffering": true + } + } + }, + { + "best_access_path": { + "table": "t_inner_2", + "plan_details": { + "record_count": 27 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.065233941, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.065233941, + "uses_join_buffering": true + } + } + }, + { + "best_access_path": { + "table": "t_inner_3", + "plan_details": { + "record_count": 27 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.065233941, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.065233941, + "uses_join_buffering": true + } + } + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4", + "table": "t_outer_2", + "rows_for_plan": 243, + "cost_for_plan": 0.102465336, + "semijoin_strategy_choice": [], + "rest_of_plan": [ + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4,t_outer_2", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t_inner_2", + "plan_details": { + "record_count": 243 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, + "uses_join_buffering": true + } + } + }, + { + "best_access_path": { + "table": "t_inner_3", + "plan_details": { + "record_count": 243 + }, + "considered_access_paths": [ + { + "access_type": "scan_with_join_cache", + "rows": 9, + "rows_after_filter": 9, + "rows_out": 9, + "cost": 0.628673451, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 9, + "rows_out": 9, + "cost": 0.628673451, + "uses_join_buffering": true + } + } + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4,t_outer_2", + "table": "t_inner_2", + "rows_for_plan": 2187, + "cost_for_plan": 0.731138787, + "semijoin_strategy_choice": [], + "pruned_by_cost": true, + "current_cost": 0.731138787, + "best_cost": 0.14187842 + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4,t_outer_2", + "table": "t_inner_3", + "rows_for_plan": 2187, + "cost_for_plan": 0.731138787, + "semijoin_strategy_choice": [], + "pruned_by_cost": true, + "current_cost": 0.731138787, + "best_cost": 0.14187842 + } + ] + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4", + "table": "t_inner_2", + "rows_for_plan": 243, + "cost_for_plan": 0.102465336, + "semijoin_strategy_choice": [], + "pruned_by_heuristic": true + }, + { + "plan_prefix": "t_outer_1,t_inner_1,t_inner_4", + "table": "t_inner_3", + "rows_for_plan": 243, + "cost_for_plan": 0.102465336, + "semijoin_strategy_choice": [], + "pruned_by_heuristic": true + } + ] }, { - "plan_prefix": ["t_outer_1", "t_inner_1"], + "plan_prefix": "t_outer_1,t_inner_1", "table": "t_inner_3", "rows_for_plan": 81, - "cost_for_plan": 24.62563477, + "cost_for_plan": 0.046471353, "semijoin_strategy_choice": [], - "pruned_by_cost": true, - "current_cost": 24.62563477, - "best_cost": 23.46152344 + "pruned_by_heuristic": true } ] }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_inner_2", "rows_for_plan": 27, - "cost_for_plan": 10.02050781, + "cost_for_plan": 0.02463804, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_inner_4", "rows_for_plan": 9, - "cost_for_plan": 6.410253906, + "cost_for_plan": 0.022028022, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": ["t_outer_1"], + "plan_prefix": "t_outer_1", "table": "t_inner_3", "rows_for_plan": 27, - "cost_for_plan": 10.02050781, + "cost_for_plan": 0.02463804, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_outer_2", "rows_for_plan": 9, - "cost_for_plan": 3.815380859, + "cost_for_plan": 0.011443245, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_2", "rows_for_plan": 9, - "cost_for_plan": 3.815380859, + "cost_for_plan": 0.011443245, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_4", "rows_for_plan": 3, - "cost_for_plan": 2.605126953, + "cost_for_plan": 0.010504815, "semijoin_strategy_choice": [], "pruned_by_heuristic": true }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t_inner_3", "rows_for_plan": 9, - "cost_for_plan": 3.815380859, + "cost_for_plan": 0.011443245, "semijoin_strategy_choice": [], "pruned_by_heuristic": true } @@ -8719,10 +10273,12 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { { "best_join_order": [ "t_outer_1", - "t_outer_2", "", + "t_outer_2", "" - ] + ], + "rows": 27, + "cost": 0.14187842 }, { "substitute_best_equal": { @@ -8730,48 +10286,52 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "resulting_condition": "1" } }, - { - "condition_on_constant_tables": "1", - "computing_condition": [] - }, { "attaching_conditions_to_tables": { - "attached_conditions_computation": [], + "attached_conditions_computation": [ + { + "condition_on_constant_tables": "1", + "computing_condition": [] + } + ], "attached_conditions_summary": [ { "table": "t_outer_1", - "attached": null - }, - { - "table": "t_outer_2", - "attached": null + "attached_condition": null }, { "table": "t_inner_1", - "attached": null + "attached_condition": null }, { "table": "t_inner_2", - "attached": null + "attached_condition": null }, { "table": "", - "attached": null + "attached_condition": null + }, + { + "table": "t_outer_2", + "attached_condition": null }, { "table": "t_inner_4", - "attached": null + "attached_condition": null }, { "table": "t_inner_3", - "attached": null + "attached_condition": null }, { "table": "", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -8826,7 +10386,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": true, "rows": 1, - "cost": 0.345829876, + "cost": 0.001478954, "chosen": true } ], @@ -8855,7 +10415,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": true, "rows": 107, - "cost": 21.63379668, + "cost": 0.016135574, "chosen": true } ], @@ -8887,7 +10447,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1000, - "cost": 1203.877243, + "cost": 1.235690484, "chosen": true } ], @@ -8927,7 +10487,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 4, - "cost": 4.948710032, + "cost": 0.00627616, "chosen": true } ], @@ -8961,7 +10521,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.346171589, + "cost": 0.002574553, "chosen": true } ], @@ -8990,7 +10550,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.346171589, + "cost": 0.002574553, "chosen": true } ], @@ -9027,7 +10587,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.345927508, + "cost": 0.002574553, "chosen": true } ], @@ -9057,7 +10617,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.345878692, + "cost": 0.002574553, "chosen": true } ], @@ -9087,7 +10647,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.345927508, + "cost": 0.002574553, "chosen": true } ], @@ -9120,7 +10680,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.345878692, + "cost": 0.002574553, "chosen": true } ], @@ -9156,7 +10716,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.394255553, + "cost": 0.002574553, "chosen": true } ], @@ -9190,7 +10750,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 2, - "cost": 2.546855016, + "cost": 0.003808422, "chosen": true } ], @@ -9214,6 +10774,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": 1.235690484, "nested_loop": [ { "table": { @@ -9223,7 +10784,9 @@ EXPLAIN "key": "start_date", "key_length": "8", "used_key_parts": ["start_date", "end_date"], + "loops": 1, "rows": 1000, + "cost": 1.235690484, "filtered": 100, "index_condition": "t1.start_date >= '2019-02-10' and t1.end_date < '2019-04-01'" } @@ -9245,7 +10808,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1000, - "cost": 1203.877243, + "cost": 1.235690484, "chosen": true } ], @@ -9295,28 +10858,35 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) [ [ { - "plan_prefix": - [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "A", + "plan_details": + { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 5, - "cost": 3.017089844, + "rows": 10, + "rows_after_filter": 5, + "rows_out": 5, + "cost": 0.01159965, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 5, - "cost": 3.017089844, + "rows_read": 5, + "rows_out": 5, + "cost": 0.01159965, "uses_join_buffering": false } } @@ -9325,20 +10895,28 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "best_access_path": { "table": "B", + "plan_details": + { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 800, - "cost": 44.19726562, + "rows": 1000, + "rows_after_filter": 800, + "rows_out": 800, + "cost": 0.1669214, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 800, - "cost": 44.19726562, + "rows_read": 800, + "rows_out": 800, + "cost": 0.1669214, "uses_join_buffering": false } } @@ -9346,36 +10924,42 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) ] }, { - "plan_prefix": - [], + "plan_prefix": "", "table": "A", "rows_for_plan": 5, - "cost_for_plan": 4.017089844, + "cost_for_plan": 0.01159965, "rest_of_plan": [ { - "plan_prefix": - ["A"], + "plan_prefix": "A", "get_costs_for_tables": [ { "best_access_path": { "table": "B", + "plan_details": + { + "record_count": 5 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 800, - "cost": 220.9863281, + "rows": 1000, + "rows_after_filter": 800, + "rows_out": 800, + "cost": 0.834607, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 800, - "cost": 220.9863281, + "rows_read": 800, + "rows_out": 800, + "cost": 0.834607, "uses_join_buffering": false } } @@ -9383,20 +10967,18 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) ] }, { - "plan_prefix": - ["A"], + "plan_prefix": "A", "table": "B", "rows_for_plan": 4000, - "cost_for_plan": 1025.003418 + "cost_for_plan": 0.84620665 } ] }, { - "plan_prefix": - [], + "plan_prefix": "", "table": "B", "rows_for_plan": 800, - "cost_for_plan": 204.1972656, + "cost_for_plan": 0.1669214, "pruned_by_heuristic": true } ] @@ -9412,28 +10994,35 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) [ [ { - "plan_prefix": - [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "A", + "plan_details": + { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 10, - "cost": 2.017089844, + "rows": 10, + "rows_after_filter": 10, + "rows_out": 10, + "cost": 0.01159965, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 2.017089844, + "rows_read": 10, + "rows_out": 10, + "cost": 0.01159965, "uses_join_buffering": false } } @@ -9442,20 +11031,28 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "best_access_path": { "table": "B", + "plan_details": + { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 800, - "cost": 44.19726562, + "rows": 1000, + "rows_after_filter": 800, + "rows_out": 800, + "cost": 0.1669214, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 800, - "cost": 44.19726562, + "rows_read": 800, + "rows_out": 800, + "cost": 0.1669214, "uses_join_buffering": false } } @@ -9463,22 +11060,24 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) ] }, { - "plan_prefix": - [], + "plan_prefix": "", "table": "A", "rows_for_plan": 10, - "cost_for_plan": 4.017089844, + "cost_for_plan": 0.01159965, "rest_of_plan": [ { - "plan_prefix": - ["A"], + "plan_prefix": "A", "get_costs_for_tables": [ { "best_access_path": { "table": "B", + "plan_details": + { + "record_count": 10 + }, "considered_access_paths": [ { @@ -9486,23 +11085,22 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "index": "b", "used_range_estimates": false, "reason": "not available", - "rowid_filter_skipped": "cost_factor <= 0", "rows": 1, - "cost": 20.00585794, + "cost": 0.01901531, "chosen": true }, { - "access_type": "scan", - "resulting_rows": 800, - "cost": 44.19726562, - "chosen": false + "type": "scan", + "chosen": false, + "cause": "cost" } ], "chosen_access_method": { "type": "ref", - "records": 1, - "cost": 20.00585794, + "rows_read": 1, + "rows_out": 1, + "cost": 0.01901531, "uses_join_buffering": false } } @@ -9510,25 +11108,26 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) ] }, { - "plan_prefix": - ["A"], + "plan_prefix": "A", "table": "B", "rows_for_plan": 10, - "cost_for_plan": 26.02294779, + "cost_for_plan": 0.03061496, + "pushdown_cond_selectivity": 0.8, + "filtered": 80, + "rows_out": 0.8, "selectivity": 0.8, "estimated_join_cardinality": 8 } ] }, { - "plan_prefix": - [], + "plan_prefix": "", "table": "B", "rows_for_plan": 800, - "cost_for_plan": 204.1972656, + "cost_for_plan": 0.1669214, "pruned_by_cost": true, - "current_cost": 204.1972656, - "best_cost": 26.02294779 + "current_cost": 0.1669214, + "best_cost": 0.03061496 } ] ] @@ -9557,7 +11156,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.357887479, + "cost": 0.002574553, "chosen": true } ], @@ -9582,9 +11181,9 @@ insert into t3 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); explain select * from t3 where (a,a) in (select t1.a, t2.a from t1, t2 where t1.b=t2.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 5 -1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where -1 PRIMARY t3 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 10 Using where +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 Using where select JSON_DETAILED(JSON_EXTRACT(trace, '$**.semijoin_table_pullout')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; JSON_DETAILED(JSON_EXTRACT(trace, '$**.semijoin_table_pullout')) [ @@ -9617,7 +11216,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) "using_mrr": false, "index_only": true, "rows": 1, - "cost": 0.345829876, + "cost": 0.001478954, "chosen": true } ] @@ -9640,28 +11239,35 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) [ [ { - "plan_prefix": - [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": + { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 10, - "cost": 2.021972656, + "rows": 10, + "rows_after_filter": 10, + "rows_out": 10, + "cost": 0.01159965, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 2.021972656, + "rows_read": 10, + "rows_out": 10, + "cost": 0.01159965, "uses_join_buffering": false } } @@ -9670,12 +11276,19 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "best_access_path": { "table": "t2", + "plan_details": + { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 100, - "cost": 2.219726562, + "rows": 100, + "rows_after_filter": 100, + "rows_out": 100, + "cost": 0.0256761, + "index_only": false, "chosen": true, "use_tmp_table": true } @@ -9683,8 +11296,9 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "chosen_access_method": { "type": "scan", - "records": 100, - "cost": 2.219726562, + "rows_read": 100, + "rows_out": 100, + "cost": 0.0256761, "uses_join_buffering": false } } @@ -9692,22 +11306,24 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) ] }, { - "plan_prefix": - [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 10, - "cost_for_plan": 4.021972656, + "cost_for_plan": 0.01159965, "rest_of_plan": [ { - "plan_prefix": - ["t1"], + "plan_prefix": "t1", "get_costs_for_tables": [ { "best_access_path": { "table": "t2", + "plan_details": + { + "record_count": 10 + }, "considered_access_paths": [ { @@ -9715,23 +11331,22 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "index": "a", "used_range_estimates": false, "reason": "not available", - "rowid_filter_skipped": "cost_factor <= 0", "rows": 1, - "cost": 20.00585794, + "cost": 0.01840091, "chosen": true }, { - "access_type": "scan", - "resulting_rows": 100, - "cost": 2.219726562, - "chosen": false + "type": "scan", + "chosen": false, + "cause": "cost" } ], "chosen_access_method": { "type": "ref", - "records": 1, - "cost": 20.00585794, + "rows_read": 1, + "rows_out": 1, + "cost": 0.01840091, "uses_join_buffering": false } } @@ -9739,32 +11354,33 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) ] }, { - "plan_prefix": - ["t1"], + "plan_prefix": "t1", "table": "t2", "rows_for_plan": 10, - "cost_for_plan": 26.0278306, - "cost_for_sorting": 10 + "cost_for_plan": 0.03000056, + "cost_for_sorting": 0.006368384 } ] }, { - "plan_prefix": - [], + "plan_prefix": "", "table": "t2", "rows_for_plan": 100, - "cost_for_plan": 22.21972656, + "cost_for_plan": 0.0256761, "rest_of_plan": [ { - "plan_prefix": - ["t2"], + "plan_prefix": "t2", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": + { + "record_count": 100 + }, "considered_access_paths": [ { @@ -9772,23 +11388,26 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "index": "a", "used_range_estimates": false, "reason": "not available", - "rowid_filter_skipped": "cost_factor <= 0", "rows": 1, - "cost": 200.0585794, + "cost": 0.1821659, "chosen": true }, { - "access_type": "scan", - "resulting_rows": 10, - "cost": 2.021972656, + "access_type": "scan_with_join_cache", + "rows": 10, + "rows_after_filter": 10, + "rows_out": 1, + "cost": 0.11055225, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10, - "cost": 2.021972656, + "rows_read": 10, + "rows_out": 1, + "cost": 0.11055225, "uses_join_buffering": true } } @@ -9796,14 +11415,13 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) ] }, { - "plan_prefix": - ["t2"], + "plan_prefix": "t2", "table": "t1", - "rows_for_plan": 1000, - "cost_for_plan": 224.2416992, + "rows_for_plan": 100, + "cost_for_plan": 0.13622835, "pruned_by_cost": true, - "current_cost": 224.2416992, - "best_cost": 36.0278306 + "current_cost": 0.13622835, + "best_cost": 0.036368944 } ] } @@ -9903,7 +11521,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) "using_mrr": false, "index_only": false, "rows": 0, - "cost": 0.145, + "cost": 0.001340684, "chosen": true } ] @@ -10005,7 +11623,8 @@ select count(*) from seq_1_to_10000000 { "table": "seq_1_to_10000000", "table_scan": { "rows": 10000000, - "cost": 10000000 + "read_cost": 124.7880673, + "read_and_compare_cost": 444.7880673 } } ] @@ -10013,23 +11632,30 @@ select count(*) from seq_1_to_10000000 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "seq_1_to_10000000", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 10000000, - "cost": 10000000, + "rows": 10000000, + "rows_after_filter": 10000000, + "rows_out": 10000000, + "cost": 444.7880673, + "index_only": true, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 10000000, - "cost": 10000000, + "rows_read": 10000000, + "rows_out": 10000000, + "cost": 444.7880673, "uses_join_buffering": false } } @@ -10037,15 +11663,17 @@ select count(*) from seq_1_to_10000000 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "seq_1_to_10000000", "rows_for_plan": 10000000, - "cost_for_plan": 12000000 + "cost_for_plan": 444.7880673 } ] }, { - "best_join_order": ["seq_1_to_10000000"] + "best_join_order": ["seq_1_to_10000000"], + "rows": 10000000, + "cost": 444.7880673 }, { "attaching_conditions_to_tables": { @@ -10053,10 +11681,13 @@ select count(*) from seq_1_to_10000000 { "attached_conditions_summary": [ { "table": "seq_1_to_10000000", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -10084,7 +11715,7 @@ explain select * from t1 left join (t2 join t3 on t3.pk=1000) on t2.a=t1.a and t2.pk is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 const PRIMARY NULL NULL NULL 1 Impossible ON condition -1 SIMPLE t2 const PRIMARY NULL NULL NULL 1 Impossible ON condition +1 SIMPLE t2 const PRIMARY NULL NULL NULL 0 Impossible ON condition 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 select JSON_DETAILED(JSON_EXTRACT(trace, '$**.mark_join_nest_as_const')) from information_schema.optimizer_trace; @@ -10109,7 +11740,7 @@ set in_predicate_conversion_threshold=3; explain select * from t0 where a in (1,2,3,4,5,6); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Using where -1 PRIMARY ref key0 key0 4 test.t0.a 2 FirstMatch(t0) +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t0.a 1 3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used select json_detailed(json_extract(trace, '$**.in_to_subquery_conversion')) from information_schema.optimizer_trace; @@ -10211,8 +11842,6 @@ S { "access_type": "ref", "index": "PRIMARY", - "rows": 1.79769e308, - "cost": 1.79769e308, "chosen": false, "cause": "no predicate for first keypart" } @@ -10374,7 +12003,7 @@ on t1.a=t.a where t1.b < 3; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 range idx_b idx_b 5 NULL 4 Using index condition; Using where -1 PRIMARY ref key0 key0 5 test.t1.a 2 +1 PRIMARY ref key0 key0 5 test.t1.a 1 2 LATERAL DERIVED t2 ref idx_a idx_a 5 test.t1.a 1 select json_detailed(json_extract(trace, '$**.choose_best_splitting')) @@ -10387,14 +12016,17 @@ json_detailed(json_extract(trace, '$**.choose_best_splitting')) "considered_execution_plans": [ { - "plan_prefix": - [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t2", + "plan_details": + { + "record_count": 1 + }, "considered_access_paths": [ { @@ -10403,7 +12035,7 @@ json_detailed(json_extract(trace, '$**.choose_best_splitting')) "used_range_estimates": false, "reason": "not available", "rows": 1.8367, - "cost": 2.000585794, + "cost": 0.002051185, "chosen": true }, { @@ -10415,8 +12047,9 @@ json_detailed(json_extract(trace, '$**.choose_best_splitting')) "chosen_access_method": { "type": "ref", - "records": 1.8367, - "cost": 2.000585794, + "rows_read": 1.8367, + "rows_out": 1.8367, + "cost": 0.002051185, "uses_join_buffering": false } } @@ -10424,23 +12057,28 @@ json_detailed(json_extract(trace, '$**.choose_best_splitting')) ] }, { - "plan_prefix": - [], + "plan_prefix": "", "table": "t2", "rows_for_plan": 1.8367, - "cost_for_plan": 2.367925794, - "cost_for_sorting": 1.8367 + "cost_for_plan": 0.002051185, + "cost_for_sorting": 0.001155201 } ] }, { - "best_splitting": + "split_materialized": { "table": "t2", "key": "idx_a", - "record_count": 4, - "cost": 2.488945919, - "unsplit_cost": 25.72361682 + "org_cost": 0.002051185, + "postjoin_cost": 0.001135418, + "one_splitting_cost": 0.003186603, + "unsplit_postjoin_cost": 0.036032575, + "unsplit_cost": 0.060625425, + "rows": 1.8367, + "outer_rows": 4, + "total_splitting_cost": 0.012746412, + "chosen": true } } ] @@ -10450,13 +12088,7 @@ json_detailed(json_extract(trace, '$**.lateral_derived')) from information_schema.optimizer_trace; json_detailed(json_extract(trace, '$**.lateral_derived')) -[ - { - "startup_cost": 9.955783677, - "splitting_cost": 2.488945919, - "records": 1 - } -] +NULL drop table t1,t2; # # Test table functions. @@ -10503,3 +12135,925 @@ left(trace, 100) set optimizer_trace='enabled=off'; # End of 10.6 tests +# +# Testing of records_out +# +set @save_optimizer_switch= @@optimizer_switch; +set @save_use_stat_tables= @@use_stat_tables; +set @save_histogram_size= @@histogram_size; +set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +set optimizer_switch='rowid_filter=on'; +set use_stat_tables='preferably'; +set histogram_size=127; +create table t1 (a int, b int, c int, key(a),key(b)); +insert into t1 select seq, seq*2, seq/10 from seq_1_to_1000; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +explain select * from t1 where a<10 and b between 10 and 50 and c < 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range|filter a,b a|b 5|5 NULL 9 (2%) Using index condition; Using where; Using rowid filter +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +explain select * from t1 where a<10 and b between 10 and 50 and c < 10 { + "steps": [ + { + "join_preparation": { + "select_id": 1, + "steps": [ + { + "expanded_query": "select t1.a AS a,t1.b AS b,t1.c AS c from t1 where t1.a < 10 and t1.b between 10 and 50 and t1.c < 10" + } + ] + } + }, + { + "join_optimization": { + "select_id": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "t1.a < 10 and t1.b between 10 and 50 and t1.c < 10", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "t1.a < 10 and t1.b between 10 and 50 and t1.c < 10" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "t1.a < 10 and t1.b between 10 and 50 and t1.c < 10" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "t1.a < 10 and t1.b between 10 and 50 and t1.c < 10" + } + ] + } + }, + { + "table_dependencies": [ + { + "table": "t1", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [] + } + ] + }, + { + "ref_optimizer_key_uses": [] + }, + { + "rows_estimation": [ + { + "table": "t1", + "range_analysis": { + "table_scan": { + "rows": 1000, + "cost": 0.1671618 + }, + "potential_range_indexes": [ + { + "index": "a", + "usable": true, + "key_parts": ["a"] + }, + { + "index": "b", + "usable": true, + "key_parts": ["b"] + } + ], + "setup_range_conditions": [], + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "a", + "ranges": ["(NULL) < (a) < (10)"], + "rowid_ordered": false, + "using_mrr": false, + "index_only": false, + "rows": 9, + "cost": 0.012445505, + "chosen": true + }, + { + "index": "b", + "ranges": ["(10) <= (b) <= (50)"], + "rowid_ordered": false, + "using_mrr": false, + "index_only": false, + "rows": 21, + "cost": 0.027251933, + "chosen": false, + "cause": "cost" + } + ], + "analyzing_roworder_intersect": { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": [] + }, + "group_index_range": { + "chosen": false, + "cause": "no group by or distinct" + }, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "range_scan", + "index": "a", + "rows": 9, + "ranges": ["(NULL) < (a) < (10)"] + }, + "rows_for_plan": 9, + "cost_for_plan": 0.012445505, + "chosen": true + } + } + }, + { + "table": "t1", + "rowid_filters": [ + { + "key": "a", + "build_cost": 9.95653e-5, + "rows": 9 + }, + { + "key": "b", + "build_cost": 3.004222e-4, + "rows": 21 + } + ] + }, + { + "selectivity_for_indexes": [ + { + "index_name": "a", + "selectivity_from_index": 0.009 + }, + { + "index_name": "b", + "selectivity_from_index": 0.021 + } + ], + "selectivity_for_columns": [ + { + "column_name": "c", + "ranges": ["NULL < c < 10"], + "selectivity_from_histogram": 0.094 + } + ], + "cond_selectivity": 0.000017766 + } + ] + }, + { + "considered_execution_plans": [ + { + "plan_prefix": "", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t1", + "plan_details": { + "record_count": 1 + }, + "considered_access_paths": [ + { + "filter": { + "rowid_filter_index": "b", + "index_only_cost": 0.001605807, + "filter_startup_cost": 3.004222e-4, + "find_key_and_filter_lookup_cost": 7.827422e-4, + "filter_selectivity": 0.021, + "original_rows": 9, + "new_rows": 0.189, + "original_access_cost": 0.011607363, + "with_filter_access_cost": 0.002598582, + "original_found_rows_cost": 0.010001556, + "with_filter_found_rows_cost": 2.100327e-4, + "org_cost": 0.011895363, + "filter_cost": 0.002905052, + "filter_used": true + }, + "access_type": "range", + "range_index": "a", + "rows": 9, + "rows_after_filter": 0.189, + "rows_out": 0.017766, + "cost": 0.002905052, + "chosen": true + } + ], + "chosen_access_method": { + "type": "range", + "rows_read": 0.189, + "rows_out": 0.017766, + "cost": 0.002905052, + "uses_join_buffering": false, + "rowid_filter_index": "b" + } + } + } + ] + }, + { + "plan_prefix": "", + "table": "t1", + "rows_for_plan": 0.017766, + "cost_for_plan": 0.002905052, + "pushdown_cond_selectivity": 0.094, + "filtered": 0.1974, + "rows_out": 0.017766 + } + ] + }, + { + "best_join_order": ["t1"], + "rows": 0.017766, + "cost": 0.002905052 + }, + { + "table": "t1", + "range_analysis": { + "potential_range_indexes": [ + { + "index": "a", + "usable": false, + "cause": "not applicable" + }, + { + "index": "b", + "usable": true, + "key_parts": ["b"] + } + ], + "setup_range_conditions": [], + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "b", + "ranges": ["(10) <= (b) <= (50)"], + "rowid_ordered": false, + "using_mrr": false, + "index_only": true, + "rows": 21, + "cost": 0.004244354, + "chosen": true + } + ] + }, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "range_scan", + "index": "b", + "rows": 21, + "ranges": ["(10) <= (b) <= (50)"] + }, + "rows_for_plan": 21, + "cost_for_plan": 0.004244354, + "chosen": true + } + } + }, + { + "substitute_best_equal": { + "condition": "WHERE", + "resulting_condition": "t1.a < 10 and t1.b between 10 and 50 and t1.c < 10" + } + }, + { + "attaching_conditions_to_tables": { + "attached_conditions_computation": [], + "attached_conditions_summary": [ + { + "table": "t1", + "attached_condition": "t1.a < 10 and t1.b between 10 and 50 and t1.c < 10" + } + ] + } + }, + { + "make_join_readinfo": [ + { + "table": "t1", + "index_condition": "t1.a < 10", + "row_condition": "t1.b between 10 and 50 and t1.c < 10" + } + ] + } + ] + } + }, + { + "join_execution": { + "select_id": 1, + "steps": [] + } + } + ] +} 0 0 +drop table t1; +create table three (a int); +insert into three values (1),(2),(3); +create table t1 (a int, b int, c int, key(a),key(b)); +insert into t1 select mod(seq,10), seq, seq from seq_1_to_10000; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +set optimizer_use_condition_selectivity=2; +explain format=json select * from three, t1 where t1.a=three.a and t1.b<5000 and t1.c<1000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 2.303362315, + "nested_loop": [ + { + "table": { + "table_name": "three", + "access_type": "ALL", + "loops": 1, + "rows": 3, + "cost": 0.010504815, + "filtered": 100, + "attached_condition": "three.a is not null" + } + }, + { + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["a", "b"], + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.three.a"], + "rowid_filter": { + "range": { + "key": "b", + "used_key_parts": ["b"] + }, + "rows": 4312, + "selectivity_pct": 43.12 + }, + "loops": 3, + "rows": 1000, + "cost": 2.2928575, + "filtered": 43.11999893, + "attached_condition": "t1.b < 5000 and t1.c < 1000" + } + } + ] + } +} +set optimizer_use_condition_selectivity=4; +explain format=json select * from three, t1 where t1.a=three.a and t1.b<5000 and t1.c<1000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 1.712236739, + "nested_loop": [ + { + "table": { + "table_name": "three", + "access_type": "ALL", + "loops": 1, + "rows": 3, + "cost": 0.010504815, + "filtered": 100 + } + }, + { + "block-nl-join": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "possible_keys": ["a", "b"], + "loops": 3, + "rows": 10000, + "cost": 1.701731924, + "filtered": 3.230766058, + "attached_condition": "t1.b < 5000 and t1.c < 1000" + }, + "buffer_type": "flat", + "buffer_size": "65", + "join_type": "BNL", + "attached_condition": "t1.a = three.a" + } + } + ] + } +} +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +explain format=json select * from three, t1 where t1.a=three.a and t1.b<5000 and t1.c<1000 { + "steps": [ + { + "join_preparation": { + "select_id": 1, + "steps": [ + { + "expanded_query": "select three.a AS a,t1.a AS a,t1.b AS b,t1.c AS c from three join t1 where t1.a = three.a and t1.b < 5000 and t1.c < 1000" + } + ] + } + }, + { + "join_optimization": { + "select_id": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "t1.a = three.a and t1.b < 5000 and t1.c < 1000", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "t1.b < 5000 and t1.c < 1000 and multiple equal(t1.a, three.a)" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "t1.b < 5000 and t1.c < 1000 and multiple equal(t1.a, three.a)" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "t1.b < 5000 and t1.c < 1000 and multiple equal(t1.a, three.a)" + } + ] + } + }, + { + "table_dependencies": [ + { + "table": "three", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [] + }, + { + "table": "t1", + "row_may_be_null": false, + "map_bit": 1, + "depends_on_map_bits": [] + } + ] + }, + { + "ref_optimizer_key_uses": [ + { + "table": "t1", + "index": "a", + "field": "a", + "equals": "three.a", + "null_rejecting": true + } + ] + }, + { + "rows_estimation": [ + { + "table": "three", + "table_scan": { + "rows": 3, + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 + } + }, + { + "table": "t1", + "range_analysis": { + "table_scan": { + "rows": 10000, + "cost": 1.581538 + }, + "potential_range_indexes": [ + { + "index": "a", + "usable": false, + "cause": "not applicable" + }, + { + "index": "b", + "usable": true, + "key_parts": ["b"] + } + ], + "setup_range_conditions": [], + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "b", + "ranges": ["(NULL) < (b) < (5000)"], + "rowid_ordered": false, + "using_mrr": false, + "index_only": false, + "rows": 4312, + "cost": 5.325149412, + "chosen": false, + "cause": "cost" + } + ], + "analyzing_roworder_intersect": { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": [] + }, + "group_index_range": { + "chosen": false, + "cause": "not single_table" + } + } + }, + { + "table": "t1", + "rowid_filters": [ + { + "key": "b", + "build_cost": 0.149564727, + "rows": 4312 + } + ] + }, + { + "selectivity_for_indexes": [ + { + "index_name": "b", + "selectivity_from_index": 0.4312 + } + ], + "selectivity_for_columns": [ + { + "column_name": "c", + "ranges": ["NULL < c < 1000"], + "selectivity_from_histogram": 0.0999 + } + ], + "cond_selectivity": 0.04307688 + } + ] + }, + { + "considered_execution_plans": [ + { + "plan_prefix": "", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "three", + "plan_details": { + "record_count": 1 + }, + "considered_access_paths": [ + { + "access_type": "scan", + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, + "uses_join_buffering": false + } + } + }, + { + "best_access_path": { + "table": "t1", + "plan_details": { + "record_count": 1 + }, + "considered_access_paths": [ + { + "access_type": "scan", + "rows": 10000, + "rows_after_filter": 430.7688, + "rows_out": 430.7688, + "cost": 1.581538, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 430.7688, + "rows_out": 430.7688, + "cost": 1.581538, + "uses_join_buffering": false + } + } + } + ] + }, + { + "plan_prefix": "", + "table": "three", + "rows_for_plan": 3, + "cost_for_plan": 0.010504815, + "rest_of_plan": [ + { + "plan_prefix": "three", + "get_costs_for_tables": [ + { + "best_access_path": { + "table": "t1", + "plan_details": { + "record_count": 3 + }, + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "used_range_estimates": false, + "reason": "not available", + "filter": { + "rowid_filter_index": "b", + "index_only_cost": 0.092096742, + "filter_startup_cost": 0.149564727, + "find_key_and_filter_lookup_cost": 0.129350121, + "filter_selectivity": 0.4312, + "original_rows": 1000, + "new_rows": 431.2, + "original_access_cost": 1.203380742, + "with_filter_access_cost": 0.700632524, + "original_found_rows_cost": 1.111284, + "with_filter_found_rows_cost": 0.479185661, + "org_cost": 3.706142226, + "filter_cost": 2.2928575, + "filter_used": true + }, + "rows": 431.2, + "cost": 2.2928575, + "chosen": true + }, + { + "access_type": "scan_with_join_cache", + "rows": 10000, + "rows_after_filter": 430.7688, + "rows_out": 323.0766, + "cost": 1.701731924, + "index_only": false, + "chosen": true + } + ], + "chosen_access_method": { + "type": "scan", + "rows_read": 430.7688, + "rows_out": 323.0766, + "cost": 1.701731924, + "uses_join_buffering": true + } + } + } + ] + }, + { + "plan_prefix": "three", + "table": "t1", + "rows_for_plan": 969.2298, + "cost_for_plan": 1.712236739, + "pushdown_cond_selectivity": 0.75, + "filtered": 3.230766, + "rows_out": 323.0766 + } + ] + }, + { + "plan_prefix": "", + "table": "t1", + "rows_for_plan": 430.7688, + "cost_for_plan": 1.581538, + "pruned_by_heuristic": true + } + ] + }, + { + "best_join_order": ["three", "t1"], + "rows": 969.2298, + "cost": 1.712236739 + }, + { + "substitute_best_equal": { + "condition": "WHERE", + "resulting_condition": "t1.a = three.a and t1.b < 5000 and t1.c < 1000" + } + }, + { + "attaching_conditions_to_tables": { + "attached_conditions_computation": [ + { + "table": "t1", + "range_analysis": { + "table_scan": { + "rows": 10000, + "cost": 1.581538 + }, + "potential_range_indexes": [ + { + "index": "a", + "usable": true, + "key_parts": ["a"] + }, + { + "index": "b", + "usable": true, + "key_parts": ["b"] + } + ], + "setup_range_conditions": [], + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "a" + }, + { + "index": "b", + "ranges": ["(NULL) < (b) < (5000)"], + "rowid_ordered": false, + "using_mrr": false, + "index_only": false, + "rows": 4312, + "cost": 5.325149412, + "chosen": false, + "cause": "cost" + } + ], + "analyzing_roworder_intersect": { + "cause": "too few roworder scans" + }, + "analyzing_index_merge_union": [] + }, + "group_index_range": { + "chosen": false, + "cause": "not single_table" + } + } + } + ], + "attached_conditions_summary": [ + { + "table": "three", + "attached_condition": null + }, + { + "table": "t1", + "attached_condition": "t1.a = three.a and t1.b < 5000 and t1.c < 1000" + } + ] + } + }, + { + "make_join_readinfo": [] + } + ] + } + }, + { + "join_execution": { + "select_id": 1, + "steps": [] + } + } + ] +} 0 0 +drop table three, t1; +# +# MDEV-21095: Index condition push down is not reflected in optimizer trace +# +create table t10 (a int, b int, c int, key(a,b)); +insert into t10 select seq, seq, seq from seq_1_to_10000; +explain format=json select * from t10 where a<3 and b!=5 and c<10; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.003808422, + "nested_loop": [ + { + "table": { + "table_name": "t10", + "access_type": "range", + "possible_keys": ["a"], + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "loops": 1, + "rows": 2, + "cost": 0.003808422, + "filtered": 100, + "index_condition": "t10.a < 3 and t10.b <> 5", + "attached_condition": "t10.c < 10" + } + } + ] + } +} +set optimizer_trace='enabled=on'; +select * from t10 where a<3 and b!=5 and c<10; +a b c +1 1 1 +2 2 2 +select json_detailed(json_extract(trace, '$**.attaching_conditions_to_tables')) as out1 +from information_schema.optimizer_trace; +out1 +[ + { + "attached_conditions_computation": + [], + "attached_conditions_summary": + [ + { + "table": "t10", + "attached_condition": "t10.a < 3 and t10.b <> 5 and t10.c < 10" + } + ] + } +] +drop table t10; +# +# MDEV-21092: EXISTS to IN is not reflected in the optimizer trace +# +set optimizer_trace='enabled=on'; +create table t1 (cn_c int, cn_n char(10), cn_a int ); +create table t2 (ci_p int, ci_c int ); +create table t3 (ci_p int, ci_c int ); +SELECT cn_n FROM t1 WHERE (EXISTS (select 1 from t2 where ci_p > 100000 and cn_c = ci_c) +OR (cn_n LIKE 'L%') ) +AND cn_a > 1000000; +cn_n +select +json_detailed( +json_extract(trace, '$.steps[*].join_optimization[0].steps[0].transformation') +) as out1 +from information_schema.optimizer_trace; +out1 +[ + { + "select_id": 2, + "from": "EXISTS (SELECT)", + "to": "IN (SELECT)", + "upper_not": false + } +] +drop table t1, t2, t3; +# +# MDEV-29997 Partition Pruning not included in optimizer tracing +# +create table t2 (a int, b int) partition by hash(a) partitions 10; +create table t3 (a int, b int) partition by hash(a) partitions 10; +INSERT INTO t2 SELECT seq, seq from seq_1_to_10; +INSERT INTO t3 SELECT seq, seq from seq_1_to_10; +set optimizer_trace='enabled=on'; +explain partitions select * from t2,t3 where t2.a in (2,3,4) and t3.a in (4,5); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t3 p4,p5 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t2 p2,p3,p4 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +select json_detailed(json_extract(trace, '$**.prune_partitions')) as out1 +from information_schema.optimizer_trace; +out1 +[ + { + "table": "t2", + "used_partitions": "p2,p3,p4" + }, + { + "table": "t3", + "used_partitions": "p4,p5" + } +] +drop table t2,t3; +create table t1 ( +a int +) partition by range (a) +( partition p0 values less than(10), +partition p1 values less than (20), +partition p2 values less than (25) +); +insert into t1 values (5),(15),(22); +explain select * from t1 where a = 28; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +select json_detailed(json_extract(trace, '$**.prune_partitions')) as out1 +from information_schema.optimizer_trace; +out1 +[ + { + "table": "t1", + "used_partitions": "" + } +] +drop table t1; +set @@optimizer_switch= @save_optimizer_switch; +set @@use_stat_tables= @save_use_stat_tables; +set @@histogram_size= @save_histogram_size; +set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index d07afb2dfce..6f8040f1689 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -85,23 +85,7 @@ drop table t1,t2,t0; --echo # group_by min max optimization --echo # CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a INT NOT NULL, KEY(a)); ---disable_query_log -INSERT INTO t1(a) VALUES (1), (2), (3), (4); -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; -INSERT INTO t1(a) SELECT a FROM t1; ---enable_query_log +insert into t1 select seq, mod(seq,4)+1 from seq_1_to_65536; analyze table t1; EXPLAIN SELECT DISTINCT a FROM t1; @@ -115,6 +99,7 @@ CREATE TABLE t1 (a INT, b INT, c int, d int, KEY(a,b,c,d)); INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4), (1,0,1,1), (3,2,3,3), (4,5,4,4); ANALYZE TABLE t1; EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a; +set statement optimizer_scan_setup_cost=0 for EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a; select * from information_schema.OPTIMIZER_TRACE; DROP TABLE t1; @@ -138,30 +123,27 @@ drop table t1; --echo # Late ORDER BY optimization --echo # -create table ten(a int); -insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -create table one_k(a int primary key); -insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C; create table t1 ( pk int not null, a int, b int, c int, filler char(100), - KEY a_a(c), + KEY c(c), KEY a_c(a,c), KEY a_b(a,b) ); -insert into t1 -select a, a,a,a, 'filler-dataaa' from test.one_k; +insert into t1 select seq, seq,seq,seq, 'filler-dataaa' from seq_0_to_999; update t1 set a=1 where pk between 0 and 180; update t1 set b=2 where pk between 0 and 20; analyze table t1; +explain select * from t1 where a=1 and b=2 order by c limit 1; +update t1 set b=2 where pk between 20 and 40; set optimizer_trace='enabled=on'; explain select * from t1 where a=1 and b=2 order by c limit 1; select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE; -drop table t1,ten,one_k; +drop table t1; --echo # --echo # TABLE ELIMINATION @@ -201,34 +183,23 @@ drop table t0, t1, t2, t3; --echo # IN subquery to sem-join is traced --echo # -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 values (0,0),(1,1),(2,2); -create table t2 as select * from t1; +insert into t1 select seq,seq from seq_0_to_3; -create table t11(a int, b int); - -create table t10 (pk int, a int); -insert into t10 select a,a from t0; -create table t12 like t10; -insert into t12 select * from t10; - -analyze table t1,t10; +create table t2 (p int, a int); +insert into t2 select seq,seq from seq_1_to_10; set optimizer_trace='enabled=on'; -explain extended select * from t1 where a in (select pk from t10); +explain extended select * from t1 where a in (select p from t2); +insert into t2 select seq,seq from seq_10_to_100; +explain extended select * from t1 where a in (select p from t2); select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE; -drop table t0,t1,t11,t10,t12,t2; +drop table t1,t2; --echo # --echo # Selectivities for columns and indexes. --echo # -create table t0 (a int); -insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); - create table t1 ( pk int, a int, @@ -236,7 +207,7 @@ b int, key pk(pk), key pk_a(pk,a), key pk_a_b(pk,a,b)); -insert into t1 select a,a,a from t0; +insert into t1 select seq,seq,seq from seq_0_to_9; ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a,b) INDEXES (); set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity; @@ -248,7 +219,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1; select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set @@use_stat_tables= @save_use_stat_tables; -drop table t0,t1; +drop table t1; set optimizer_trace="enabled=off"; --echo # @@ -928,3 +899,106 @@ set optimizer_trace='enabled=off'; --echo # End of 10.6 tests + +--echo # +--echo # Testing of records_out +--echo # + +set @save_optimizer_switch= @@optimizer_switch; +set @save_use_stat_tables= @@use_stat_tables; +set @save_histogram_size= @@histogram_size; +set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +set optimizer_switch='rowid_filter=on'; +set use_stat_tables='preferably'; +set histogram_size=127; +create table t1 (a int, b int, c int, key(a),key(b)); +insert into t1 select seq, seq*2, seq/10 from seq_1_to_1000; +analyze table t1; +--optimizer_trace +explain select * from t1 where a<10 and b between 10 and 50 and c < 10; +drop table t1; + +create table three (a int); +insert into three values (1),(2),(3); +create table t1 (a int, b int, c int, key(a),key(b)); +insert into t1 select mod(seq,10), seq, seq from seq_1_to_10000; +analyze table t1; + +set optimizer_use_condition_selectivity=2; +explain format=json select * from three, t1 where t1.a=three.a and t1.b<5000 and t1.c<1000; +set optimizer_use_condition_selectivity=4; +--optimizer_trace +explain format=json select * from three, t1 where t1.a=three.a and t1.b<5000 and t1.c<1000; + +drop table three, t1; + +--echo # +--echo # MDEV-21095: Index condition push down is not reflected in optimizer trace +--echo # +create table t10 (a int, b int, c int, key(a,b)); +insert into t10 select seq, seq, seq from seq_1_to_10000; +explain format=json select * from t10 where a<3 and b!=5 and c<10; +set optimizer_trace='enabled=on'; +select * from t10 where a<3 and b!=5 and c<10; +select json_detailed(json_extract(trace, '$**.attaching_conditions_to_tables')) as out1 +from information_schema.optimizer_trace; +drop table t10; + +--echo # +--echo # MDEV-21092: EXISTS to IN is not reflected in the optimizer trace +--echo # +# EXISTS-to-IN conversion is traced on PREPARE so won't be visible with a VIEW: +--disable_view_protocol +set optimizer_trace='enabled=on'; + +create table t1 (cn_c int, cn_n char(10), cn_a int ); +create table t2 (ci_p int, ci_c int ); +create table t3 (ci_p int, ci_c int ); + +SELECT cn_n FROM t1 WHERE (EXISTS (select 1 from t2 where ci_p > 100000 and cn_c = ci_c) + OR (cn_n LIKE 'L%') ) + AND cn_a > 1000000; + +select + json_detailed( + json_extract(trace, '$.steps[*].join_optimization[0].steps[0].transformation') + ) as out1 +from information_schema.optimizer_trace; + +--enable_view_protocol +drop table t1, t2, t3; + +--echo # +--echo # MDEV-29997 Partition Pruning not included in optimizer tracing +--echo # +--source include/have_partition.inc +create table t2 (a int, b int) partition by hash(a) partitions 10; +create table t3 (a int, b int) partition by hash(a) partitions 10; +INSERT INTO t2 SELECT seq, seq from seq_1_to_10; +INSERT INTO t3 SELECT seq, seq from seq_1_to_10; + +set optimizer_trace='enabled=on'; +explain partitions select * from t2,t3 where t2.a in (2,3,4) and t3.a in (4,5); +select json_detailed(json_extract(trace, '$**.prune_partitions')) as out1 +from information_schema.optimizer_trace; +drop table t2,t3; + +create table t1 ( + a int +) partition by range (a) +( partition p0 values less than(10), + partition p1 values less than (20), + partition p2 values less than (25) +); +insert into t1 values (5),(15),(22); + +explain select * from t1 where a = 28; +select json_detailed(json_extract(trace, '$**.prune_partitions')) as out1 +from information_schema.optimizer_trace; +drop table t1; + +set @@optimizer_switch= @save_optimizer_switch; +set @@use_stat_tables= @save_use_stat_tables; +set @@histogram_size= @save_histogram_size; +set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; + diff --git a/mysql-test/main/opt_trace_index_merge.result b/mysql-test/main/opt_trace_index_merge.result index 0ffa930e2b0..5f111e4836e 100644 --- a/mysql-test/main/opt_trace_index_merge.result +++ b/mysql-test/main/opt_trace_index_merge.result @@ -73,7 +73,7 @@ explain select * from t1 where a=1 or b=1 { "range_analysis": { "table_scan": { "rows": 1000, - "cost": 231.5878906 + "cost": 0.1729314 }, "potential_range_indexes": [ { @@ -98,7 +98,9 @@ explain select * from t1 where a=1 or b=1 { "analyzing_roworder_intersect": { "cause": "too few roworder scans" }, - "analyzing_sort_intersect": {}, + "analyzing_sort_intersect": { + "cutoff_cost": 0.1729314 + }, "analyzing_index_merge_union": [ { "indexes_to_merge": [ @@ -111,12 +113,12 @@ explain select * from t1 where a=1 or b=1 { "using_mrr": false, "index_only": true, "rows": 1, - "cost": 0.345585794, + "cost": 0.001478954, "chosen": true } ], "index_to_merge": "a", - "cumulated_cost": 0.345585794 + "cumulated_cost": 0.001478954 }, { "range_scan_alternatives": [ @@ -127,15 +129,15 @@ explain select * from t1 where a=1 or b=1 { "using_mrr": false, "index_only": true, "rows": 1, - "cost": 0.345585794, + "cost": 0.001478954, "chosen": true } ], "index_to_merge": "b", - "cumulated_cost": 0.691171589 + "cumulated_cost": 0.002957908 } ], - "cost_of_reading_ranges": 0.691171589, + "cost_of_reading_ranges": 0.002957908, "use_roworder_union": true, "cause": "always cheaper than non roworder retrieval", "analyzing_roworder_scans": [ @@ -158,7 +160,7 @@ explain select * from t1 where a=1 or b=1 { } } ], - "index_roworder_union_cost": 2.484903732, + "index_roworder_union_cost": 0.005185782, "members": 2, "chosen": true } @@ -187,13 +189,17 @@ explain select * from t1 where a=1 or b=1 { ] }, "rows_for_plan": 2, - "cost_for_plan": 2.484903732, + "cost_for_plan": 0.005185782, "chosen": true } } }, { - "selectivity_for_indexes": [], + "selectivity_for_indexes": [ + { + "use_opt_range_condition_rows_selectivity": 0.002 + } + ], "selectivity_for_columns": [], "cond_selectivity": 0.002 } @@ -202,23 +208,29 @@ explain select * from t1 where a=1 or b=1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "index_merge", - "resulting_rows": 2, - "cost": 2.484903732, + "rows": 2, + "rows_after_filter": 2, + "rows_out": 2, + "cost": 0.005185782, "chosen": true } ], "chosen_access_method": { "type": "index_merge", - "records": 2, - "cost": 2.484903732, + "rows_read": 2, + "rows_out": 2, + "cost": 0.005185782, "uses_join_buffering": false } } @@ -226,15 +238,17 @@ explain select * from t1 where a=1 or b=1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 2, - "cost_for_plan": 2.884903732 + "cost_for_plan": 0.005185782 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 2, + "cost": 0.005185782 }, { "substitute_best_equal": { @@ -248,10 +262,13 @@ explain select * from t1 where a=1 or b=1 { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.a = 1 or t1.b = 1" + "attached_condition": "t1.a = 1 or t1.b = 1" } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -315,7 +332,7 @@ set optimizer_trace='enabled=on'; # 3-way ROR-intersection explain select key1,key2,key3 from t1 where key1=100 and key2=100 and key3=100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge key1,key2,key3 key1,key2,key3 5,5,5 NULL 2 Using intersect(key1,key2,key3); Using where; Using index +1 SIMPLE t1 index_merge key1,key2,key3 key1,key2 5,5 NULL 77 Using intersect(key1,key2); Using where select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) [ @@ -330,7 +347,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 2243, - "cost": 2700.058937, + "cost": 2.770351251, "chosen": true }, { @@ -341,7 +358,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 2243, - "cost": 2700.058937, + "cost": 2.770351251, "chosen": false, "cause": "cost" }, @@ -353,7 +370,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 2243, - "cost": 2700.058937, + "cost": 2.770351251, "chosen": false, "cause": "cost" } @@ -364,10 +381,10 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) [ { "index": "key1", - "index_scan_cost": 10.31393703, - "cumulated_index_scan_cost": 10.31393703, - "disk_sweep_cost": 1923.144061, - "cumulative_total_cost": 1933.457998, + "index_scan_cost": 0.240986767, + "cumulated_index_scan_cost": 0.240986767, + "disk_sweep_cost": 2.564386012, + "cumulative_total_cost": 2.805372779, "usable": true, "matching_rows_now": 2243, "intersect_covering_with_this_index": false, @@ -375,10 +392,10 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) }, { "index": "key2", - "index_scan_cost": 10.31393703, - "cumulated_index_scan_cost": 20.62787405, - "disk_sweep_cost": 84.51771758, - "cumulative_total_cost": 105.1455916, + "index_scan_cost": 0.240986767, + "cumulated_index_scan_cost": 0.481973534, + "disk_sweep_cost": 0.088032868, + "cumulative_total_cost": 0.570006402, "usable": true, "matching_rows_now": 77.6360508, "intersect_covering_with_this_index": false, @@ -386,14 +403,15 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) }, { "index": "key3", - "index_scan_cost": 10.31393703, - "cumulated_index_scan_cost": 30.94181108, + "index_scan_cost": 0.240986767, + "cumulated_index_scan_cost": 0.722960301, "disk_sweep_cost": 0, - "cumulative_total_cost": 30.94181108, + "cumulative_total_cost": 0.722960301, "usable": true, "matching_rows_now": 2.687185191, "intersect_covering_with_this_index": true, - "chosen": true + "chosen": false, + "cause": "does not reduce cost" } ], "clustered_pk": @@ -401,9 +419,9 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "clustered_pk_added_to_intersect": false, "cause": "no clustered pk index" }, - "rows": 2, - "cost": 30.94181108, - "covering": true, + "rows": 77, + "cost": 0.572490756, + "covering": false, "chosen": true }, "analyzing_index_merge_union": @@ -417,9 +435,9 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.chosen_range_access_summary')) "range_access_plan": { "type": "index_roworder_intersect", - "rows": 2, - "cost": 30.94181108, - "covering": true, + "rows": 77, + "cost": 0.572490756, + "covering": false, "clustered_pk_scan": false, "intersect_of": [ @@ -436,18 +454,11 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.chosen_range_access_summary')) "rows": 2243, "ranges": ["(100) <= (key2) <= (100)"] - }, - { - "type": "range_scan", - "index": "key3", - "rows": 2243, - "ranges": - ["(100) <= (key3) <= (100)"] } ] }, - "rows_for_plan": 2, - "cost_for_plan": 30.94181108, + "rows_for_plan": 77, + "cost_for_plan": 0.572490756, "chosen": true } ] @@ -481,7 +492,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": true, "rows": 2243, - "cost": 457.058937, + "cost": 0.312922694, "chosen": true }, { @@ -492,13 +503,13 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": true, "rows": 2243, - "cost": 457.058937, + "cost": 0.312922694, "chosen": false, "cause": "cost" } ], "index_to_merge": "key1", - "cumulated_cost": 457.058937 + "cumulated_cost": 0.312922694 }, { "range_scan_alternatives": @@ -511,7 +522,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": true, "rows": 2243, - "cost": 457.058937, + "cost": 0.312922694, "chosen": true }, { @@ -522,16 +533,16 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": true, "rows": 2243, - "cost": 457.058937, + "cost": 0.312922694, "chosen": false, "cause": "cost" } ], "index_to_merge": "key3", - "cumulated_cost": 914.1178741 + "cumulated_cost": 0.625845388 } ], - "cost_of_reading_ranges": 914.1178741, + "cost_of_reading_ranges": 0.625845388, "use_roworder_union": true, "cause": "always cheaper than non roworder retrieval", "analyzing_roworder_scans": @@ -548,10 +559,10 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) [ { "index": "key1", - "index_scan_cost": 10.31393703, - "cumulated_index_scan_cost": 10.31393703, - "disk_sweep_cost": 1923.144061, - "cumulative_total_cost": 1933.457998, + "index_scan_cost": 0.240986767, + "cumulated_index_scan_cost": 0.240986767, + "disk_sweep_cost": 2.564386012, + "cumulative_total_cost": 2.805372779, "usable": true, "matching_rows_now": 2243, "intersect_covering_with_this_index": false, @@ -559,10 +570,10 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) }, { "index": "key2", - "index_scan_cost": 10.31393703, - "cumulated_index_scan_cost": 20.62787405, - "disk_sweep_cost": 84.51771758, - "cumulative_total_cost": 105.1455916, + "index_scan_cost": 0.240986767, + "cumulated_index_scan_cost": 0.481973534, + "disk_sweep_cost": 0.088032868, + "cumulative_total_cost": 0.570006402, "usable": true, "matching_rows_now": 77.6360508, "intersect_covering_with_this_index": false, @@ -575,7 +586,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "cause": "no clustered pk index" }, "rows": 77, - "cost": 105.1455916, + "cost": 0.572490756, "covering": false, "chosen": true } @@ -592,10 +603,10 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) [ { "index": "key3", - "index_scan_cost": 10.31393703, - "cumulated_index_scan_cost": 10.31393703, - "disk_sweep_cost": 1923.144061, - "cumulative_total_cost": 1933.457998, + "index_scan_cost": 0.240986767, + "cumulated_index_scan_cost": 0.240986767, + "disk_sweep_cost": 2.564386012, + "cumulative_total_cost": 2.805372779, "usable": true, "matching_rows_now": 2243, "intersect_covering_with_this_index": false, @@ -603,10 +614,10 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) }, { "index": "key4", - "index_scan_cost": 10.31393703, - "cumulated_index_scan_cost": 20.62787405, - "disk_sweep_cost": 84.51771758, - "cumulative_total_cost": 105.1455916, + "index_scan_cost": 0.240986767, + "cumulated_index_scan_cost": 0.481973534, + "disk_sweep_cost": 0.088032868, + "cumulative_total_cost": 0.570006402, "usable": true, "matching_rows_now": 77.6360508, "intersect_covering_with_this_index": false, @@ -619,13 +630,13 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "cause": "no clustered pk index" }, "rows": 77, - "cost": 105.1455916, + "cost": 0.572490756, "covering": false, "chosen": true } } ], - "index_roworder_union_cost": 194.9771115, + "index_roworder_union_cost": 1.135493366, "members": 2, "chosen": true } @@ -644,7 +655,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.chosen_range_access_summary')) { "type": "index_roworder_intersect", "rows": 77, - "cost": 105.1455916, + "cost": 0.572490756, "covering": false, "clustered_pk_scan": false, "intersect_of": @@ -668,7 +679,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.chosen_range_access_summary')) { "type": "index_roworder_intersect", "rows": 77, - "cost": 105.1455916, + "cost": 0.572490756, "covering": false, "clustered_pk_scan": false, "intersect_of": @@ -692,7 +703,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.chosen_range_access_summary')) ] }, "rows_for_plan": 154, - "cost_for_plan": 194.9771115, + "cost_for_plan": 1.135493366, "chosen": true } ] diff --git a/mysql-test/main/opt_trace_index_merge_innodb.result b/mysql-test/main/opt_trace_index_merge_innodb.result index adb9cd5d622..635301b0d18 100644 --- a/mysql-test/main/opt_trace_index_merge_innodb.result +++ b/mysql-test/main/opt_trace_index_merge_innodb.result @@ -89,7 +89,7 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "range_analysis": { "table_scan": { "rows": 1000, - "cost": 206 + "cost": 0.1764192 }, "potential_range_indexes": [ { @@ -118,8 +118,9 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "using_mrr": false, "index_only": false, "rows": 1000, - "cost": 204.27, - "chosen": true + "cost": 0.19598856, + "chosen": false, + "cause": "cost" }, { "index": "key1", @@ -128,7 +129,7 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "using_mrr": false, "index_only": false, "rows": 1, - "cost": 1.345146475, + "cost": 0.00424968, "chosen": true } ], @@ -136,10 +137,10 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "intersecting_indexes": [ { "index": "key1", - "index_scan_cost": 1.000146475, - "cumulated_index_scan_cost": 1.000146475, - "disk_sweep_cost": 1.004153686, - "cumulative_total_cost": 2.004300162, + "index_scan_cost": 0.001661605, + "cumulated_index_scan_cost": 0.001661605, + "disk_sweep_cost": 0.00171364, + "cumulative_total_cost": 0.003375245, "usable": true, "matching_rows_now": 1, "intersect_covering_with_this_index": false, @@ -151,7 +152,7 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "cause": "cost" }, "chosen": false, - "cause": "cost" + "cause": "too few indexes to merge" }, "analyzing_index_merge_union": [] }, @@ -167,7 +168,7 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "ranges": ["(1) <= (key1) <= (1)"] }, "rows_for_plan": 1, - "cost_for_plan": 1.345146475, + "cost_for_plan": 0.00424968, "chosen": true } } @@ -177,7 +178,7 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "rowid_filters": [ { "key": "key1", - "build_cost": 0.130146475, + "build_cost": 0.000002653, "rows": 1 } ] @@ -201,18 +202,21 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "ref", "index": "key1", "used_range_estimates": true, "rows": 1, - "cost": 1.125146475, + "cost": 0.00345856, "chosen": true }, { @@ -223,8 +227,9 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { ], "chosen_access_method": { "type": "ref", - "records": 1, - "cost": 1.125146475, + "rows_read": 1, + "rows_out": 1, + "cost": 0.00345856, "uses_join_buffering": false } } @@ -232,15 +237,17 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 1, - "cost_for_plan": 1.325146475 + "cost_for_plan": 0.00345856 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 1, + "cost": 0.00345856 }, { "substitute_best_equal": { @@ -254,10 +261,18 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "attached_conditions_summary": [ { "table": "t1", - "attached": "t1.pk1 <> 0" + "attached_condition": "t1.pk1 <> 0" } ] } + }, + { + "make_join_readinfo": [ + { + "table": "t1", + "index_condition": "t1.pk1 <> 0" + } + ] } ] } diff --git a/mysql-test/main/opt_trace_security.result b/mysql-test/main/opt_trace_security.result index 48ca5c5e36f..9ef6cadec5f 100644 --- a/mysql-test/main/opt_trace_security.result +++ b/mysql-test/main/opt_trace_security.result @@ -80,7 +80,8 @@ select * from db1.t1 { "table": "t1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } } ] @@ -88,23 +89,30 @@ select * from db1.t1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -112,15 +120,17 @@ select * from db1.t1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953 + "cost_for_plan": 0.010504815 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 3, + "cost": 0.010504815 }, { "attaching_conditions_to_tables": { @@ -128,10 +138,13 @@ select * from db1.t1 { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } @@ -209,7 +222,8 @@ select * from db1.v1 { "table": "t1", "table_scan": { "rows": 3, - "cost": 2.005126953 + "read_cost": 0.010408815, + "read_and_compare_cost": 0.010504815 } } ] @@ -217,23 +231,30 @@ select * from db1.v1 { { "considered_execution_plans": [ { - "plan_prefix": [], + "plan_prefix": "", "get_costs_for_tables": [ { "best_access_path": { "table": "t1", + "plan_details": { + "record_count": 1 + }, "considered_access_paths": [ { "access_type": "scan", - "resulting_rows": 3, - "cost": 2.005126953, + "rows": 3, + "rows_after_filter": 3, + "rows_out": 3, + "cost": 0.010504815, + "index_only": false, "chosen": true } ], "chosen_access_method": { "type": "scan", - "records": 3, - "cost": 2.005126953, + "rows_read": 3, + "rows_out": 3, + "cost": 0.010504815, "uses_join_buffering": false } } @@ -241,15 +262,17 @@ select * from db1.v1 { ] }, { - "plan_prefix": [], + "plan_prefix": "", "table": "t1", "rows_for_plan": 3, - "cost_for_plan": 2.605126953 + "cost_for_plan": 0.010504815 } ] }, { - "best_join_order": ["t1"] + "best_join_order": ["t1"], + "rows": 3, + "cost": 0.010504815 }, { "attaching_conditions_to_tables": { @@ -257,10 +280,13 @@ select * from db1.v1 { "attached_conditions_summary": [ { "table": "t1", - "attached": null + "attached_condition": null } ] } + }, + { + "make_join_readinfo": [] } ] } diff --git a/mysql-test/main/opt_trace_selectivity.result b/mysql-test/main/opt_trace_selectivity.result new file mode 100644 index 00000000000..d6abad79637 --- /dev/null +++ b/mysql-test/main/opt_trace_selectivity.result @@ -0,0 +1,369 @@ +create or replace table t1 (a int, b int, c int, key(a,c), key(b,c), key (c,b)) engine=aria; +insert into t1 select seq/100+1, mod(seq,10), mod(seq,15) from seq_1_to_10000; +insert into t1 select seq/100+1, mod(seq,10), 10 from seq_1_to_1000; +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +select count(*) from t1 where a=2; +count(*) +200 +select count(*) from t1 where b=5; +count(*) +1100 +select count(*) from t1 where c=5; +count(*) +667 +select count(*) from t1 where c=10; +count(*) +1667 +select count(*) from t1 where a=2 and b=5; +count(*) +20 +select count(*) from t1 where c=10 and b=5; +count(*) +433 +select count(*) from t1 where c=5 and b=5; +count(*) +334 +set optimizer_trace="enabled=on"; +select count(*) from t1 where a=2 and b=5 and c=10; +count(*) +14 +set @trace=(select trace from INFORMATION_SCHEMA.OPTIMIZER_TRACE); +select +JSON_DETAILED( +JSON_EXTRACT( +JSON_EXTRACT(@trace, '$**.considered_execution_plans'), +'$[0]' + ) +) as JS; +JS +[ + { + "plan_prefix": "", + "get_costs_for_tables": + [ + { + "best_access_path": + { + "table": "t1", + "plan_details": + { + "record_count": 1 + }, + "considered_access_paths": + [ + { + "access_type": "ref", + "index": "a", + "used_range_estimates": true, + "rows": 104, + "cost": 0.060988785, + "chosen": true + }, + { + "access_type": "ref", + "index": "b", + "used_range_estimates": true, + "rows": 340, + "cost": 0.141618657, + "chosen": false, + "cause": "cost" + }, + { + "access_type": "ref", + "index": "c", + "used_range_estimates": true, + "rows": 632, + "cost": 0.241826241, + "chosen": false, + "cause": "cost" + }, + { + "access_type": "index_merge", + "rows": 7, + "rows_after_filter": 7, + "rows_out": 7, + "cost": 0.045367017, + "chosen": true + } + ], + "chosen_access_method": + { + "type": "index_merge", + "rows_read": 7, + "rows_out": 7, + "cost": 0.045367017, + "uses_join_buffering": false + } + } + } + ] + }, + { + "plan_prefix": "", + "table": "t1", + "rows_for_plan": 7, + "cost_for_plan": 0.045367017 + } +] +select JSON_DETAILED(JSON_EXTRACT(@trace, '$**.selectivity_for_indexes')) as JS; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.009454545 + }, + { + "index_name": "b", + "selectivity_from_index": 0.1 + }, + { + "use_opt_range_condition_rows_selectivity": 6.363636e-4 + } + ] +] +select count(*) from t1 where a=2 and b=5 and c=5; +count(*) +3 +set @trace=(select trace from INFORMATION_SCHEMA.OPTIMIZER_TRACE); +select +JSON_DETAILED( +JSON_EXTRACT( +JSON_EXTRACT(@trace, '$**.considered_execution_plans'), +'$[0]' + ) +) as JS; +JS +[ + { + "plan_prefix": "", + "get_costs_for_tables": + [ + { + "best_access_path": + { + "table": "t1", + "plan_details": + { + "record_count": 1 + }, + "considered_access_paths": + [ + { + "access_type": "ref", + "index": "a", + "used_range_estimates": true, + "rows": 6, + "cost": 0.005388489, + "chosen": true + }, + { + "access_type": "ref", + "index": "b", + "used_range_estimates": true, + "rows": 232, + "cost": 0.104720241, + "chosen": false, + "cause": "cost" + }, + { + "access_type": "ref", + "index": "c", + "used_range_estimates": true, + "rows": 293, + "cost": 0.125561013, + "chosen": false, + "cause": "cost" + }, + { + "type": "scan", + "chosen": false, + "cause": "cost" + } + ], + "chosen_access_method": + { + "type": "ref", + "rows_read": 6, + "rows_out": 0.6, + "cost": 0.005388489, + "uses_join_buffering": false + } + } + } + ] + }, + { + "plan_prefix": "", + "table": "t1", + "rows_for_plan": 0.6, + "cost_for_plan": 0.005388489, + "pushdown_cond_selectivity": 0.1, + "filtered": 10, + "rows_out": 0.6 + } +] +select JSON_DETAILED(JSON_EXTRACT(@trace, '$**.selectivity_for_indexes')) as JS; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 5.454545e-4 + }, + { + "index_name": "b", + "selectivity_from_index": 0.1 + } + ] +] +# Ensure that we only use selectivity from non used index for simple cases +select count(*) from t1 where (a=2 and b= 5); +count(*) +20 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.017545455 + }, + { + "index_name": "b", + "selectivity_from_index": 0.073181818 + } + ] +] +# All of the following should have selectivity=1 for index 'b' +select count(*) from t1 where (a=2 and b between 0 and 100); +count(*) +200 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.017545455 + }, + { + "index_name": "b", + "selectivity_from_index": 1 + } + ] +] +select count(*) from t1 where (a in (2,3) and b between 0 and 100); +count(*) +400 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.035090909 + }, + { + "index_name": "b", + "selectivity_from_index": 1 + } + ] +] +select count(*) from t1 where (a>2 and b between 0 and 100); +count(*) +10702 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.973909091 + }, + { + "index_name": "b", + "selectivity_from_index": 1 + } + ] +] +select count(*) from t1 where (a>=2 and b between 0 and 100); +count(*) +10902 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.991454545 + }, + { + "index_name": "b", + "selectivity_from_index": 1 + } + ] +] +select count(*) from t1 where (a<=2 and b between 0 and 100); +count(*) +298 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.026181818 + }, + { + "index_name": "b", + "selectivity_from_index": 1 + } + ] +] +select count(*) from t1 where (a<2 and b between 0 and 100); +count(*) +98 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.008636364 + }, + { + "index_name": "b", + "selectivity_from_index": 1 + } + ] +] +select count(*) from t1 where (a between 2 and 3 and b between 0 and 100); +count(*) +400 +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + [ + { + "index_name": "a", + "selectivity_from_index": 0.035090909 + }, + { + "index_name": "b", + "selectivity_from_index": 1 + } + ] +] +drop table t1; +set optimizer_trace='enabled=off'; diff --git a/mysql-test/main/opt_trace_selectivity.test b/mysql-test/main/opt_trace_selectivity.test new file mode 100644 index 00000000000..40f78d91db7 --- /dev/null +++ b/mysql-test/main/opt_trace_selectivity.test @@ -0,0 +1,86 @@ +--source include/have_sequence.inc +--source include/not_embedded.inc + +# +# Test changes in calculate_cond_selectivity_for_table() +# +create or replace table t1 (a int, b int, c int, key(a,c), key(b,c), key (c,b)) engine=aria; +insert into t1 select seq/100+1, mod(seq,10), mod(seq,15) from seq_1_to_10000; +insert into t1 select seq/100+1, mod(seq,10), 10 from seq_1_to_1000; +optimize table t1; + +select count(*) from t1 where a=2; +select count(*) from t1 where b=5; +select count(*) from t1 where c=5; +select count(*) from t1 where c=10; +select count(*) from t1 where a=2 and b=5; +select count(*) from t1 where c=10 and b=5; +select count(*) from t1 where c=5 and b=5; + +set optimizer_trace="enabled=on"; +select count(*) from t1 where a=2 and b=5 and c=10; + +set @trace=(select trace from INFORMATION_SCHEMA.OPTIMIZER_TRACE); + +# The second JSON_EXTRACT is for --view-protocol which wraps every select: +select + JSON_DETAILED( + JSON_EXTRACT( + JSON_EXTRACT(@trace, '$**.considered_execution_plans'), + '$[0]' + ) + ) as JS; + +select JSON_DETAILED(JSON_EXTRACT(@trace, '$**.selectivity_for_indexes')) as JS; + +select count(*) from t1 where a=2 and b=5 and c=5; +set @trace=(select trace from INFORMATION_SCHEMA.OPTIMIZER_TRACE); + +# The second JSON_EXTRACT is for --view-protocol which wraps every select: +select + JSON_DETAILED( + JSON_EXTRACT( + JSON_EXTRACT(@trace, '$**.considered_execution_plans'), + '$[0]' + ) + ) as JS; +select JSON_DETAILED(JSON_EXTRACT(@trace, '$**.selectivity_for_indexes')) as JS; + +--echo # Ensure that we only use selectivity from non used index for simple cases + + +select count(*) from t1 where (a=2 and b= 5); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +--echo # All of the following should have selectivity=1 for index 'b' +select count(*) from t1 where (a=2 and b between 0 and 100); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +select count(*) from t1 where (a in (2,3) and b between 0 and 100); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +select count(*) from t1 where (a>2 and b between 0 and 100); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +select count(*) from t1 where (a>=2 and b between 0 and 100); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +select count(*) from t1 where (a<=2 and b between 0 and 100); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +select count(*) from t1 where (a<2 and b between 0 and 100); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +select count(*) from t1 where (a between 2 and 3 and b between 0 and 100); +select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_indexes')) as JS +from INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +drop table t1; +set optimizer_trace='enabled=off'; diff --git a/mysql-test/main/opt_trace_ucs2.result b/mysql-test/main/opt_trace_ucs2.result index 9e4f25f3150..e89750ec3b0 100644 --- a/mysql-test/main/opt_trace_ucs2.result +++ b/mysql-test/main/opt_trace_ucs2.result @@ -7,6 +7,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -16,7 +17,9 @@ EXPLAIN "key": "col1", "key_length": "21", "used_key_parts": ["col1"], + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.col1 >= 'a'" } @@ -38,7 +41,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) "using_mrr": false, "index_only": false, "rows": 2, - "cost": 2.547733708, + "cost": 0.003808422, "chosen": true } ], diff --git a/mysql-test/main/opt_trace_ucs2.test b/mysql-test/main/opt_trace_ucs2.test index 1a79ea9780e..7e06955d666 100644 --- a/mysql-test/main/opt_trace_ucs2.test +++ b/mysql-test/main/opt_trace_ucs2.test @@ -5,6 +5,7 @@ create or replace table t1 (col1 char(10) character set ucs2, filler char(100), insert into t1 values ('a', 'a'); insert into t1 values ('a', 'a'); set optimizer_trace=1; +--source include/explain-no-costs.inc explain format=json select * from t1 force index(col1) where col1 >='a'; #enable after fix MDEV-27871 --disable_view_protocol diff --git a/mysql-test/main/opt_tvc.result b/mysql-test/main/opt_tvc.result index eaf75ed7999..c08c68eb7ee 100644 --- a/mysql-test/main/opt_tvc.result +++ b/mysql-test/main/opt_tvc.result @@ -46,12 +46,11 @@ a b 2 5 explain extended select * from t1 where a in (1,2); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`_col_1` = `test`.`t1`.`a` explain extended select * from t1 where a in ( @@ -59,12 +58,49 @@ select * from (values (1),(2)) as tvc_0 ); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` +select * from t1 where a in (1,2,2,2,3,4,5,6,7); +a b +1 2 +4 6 +1 1 +2 5 +7 8 +select * from t1 +where a in +( +select * +from (values (1),(2),(2),(2),(2),(3),(4),(5),(6),(7)) as tvc_0 +); +a b +1 2 +4 6 +1 1 +2 5 +7 8 +explain extended select * from t1 where a in (1,2,2,2,3,4,5,6,7); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2),(2),(2),(3),(4),(5),(6),(7)) `tvc_0` join `test`.`t1` where `tvc_0`.`_col_1` = `test`.`t1`.`a` +explain extended select * from t1 +where a in +( +select * +from (values (1),(2),(2),(2),(2),(3),(4),(5),(6),(7)) as tvc_0 +); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2),(2),(2),(2),(3),(4),(5),(6),(7)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` # AND-condition with IN-predicates in WHERE-part select * from t1 where a in (1,2) and @@ -90,15 +126,13 @@ explain extended select * from t1 where a in (1,2) and b in (1,5); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 -4 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.b 1 100.00 5 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) semi join ((values (1),(5)) `tvc_1`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(5)) `tvc_1` join (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`_col_1` = `test`.`t1`.`a` and `tvc_1`.`_col_1` = `test`.`t1`.`b` explain extended select * from t1 where a in ( @@ -111,15 +145,13 @@ select * from (values (1),(5)) as tvc_1 ); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 -4 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.b 1 100.00 5 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) semi join ((values (1),(5)) `tvc_1`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(5)) `tvc_1` join (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` and `tvc_1`.`1` = `test`.`t1`.`b` # subquery with IN-predicate select * from t1 where a in @@ -150,11 +182,11 @@ from t2 where b in (3,4) id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where +2 MATERIALIZED eq_ref distinct_key distinct_key 4 test.t2.b 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (3),(4)) `tvc_0` join `test`.`t2`) where `test`.`t2`.`b` = `tvc_0`.`_col_1` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (3),(4)) `tvc_0` join `test`.`t2`) where `tvc_0`.`_col_1` = `test`.`t2`.`b` explain extended select * from t1 where a in ( @@ -168,11 +200,11 @@ from (values (3),(4)) as tvc_0 id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where +2 MATERIALIZED eq_ref distinct_key distinct_key 4 test.t2.b 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (3),(4)) `tvc_0` join `test`.`t2`) where `test`.`t2`.`b` = `tvc_0`.`3` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (3),(4)) `tvc_0` join `test`.`t2`) where `tvc_0`.`3` = `test`.`t2`.`b` # derived table with IN-predicate select * from ( @@ -206,12 +238,11 @@ from t1 where a in (1,2) ) as dr_table; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`_col_1` = `test`.`t1`.`a` explain extended select * from ( select * @@ -224,12 +255,11 @@ as tvc_0 ) ) as dr_table; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` # non-recursive CTE with IN-predicate with tvc_0 as ( @@ -265,12 +295,11 @@ where a in (1,2) ) select * from tvc_0; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 with tvc_0 as (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where `test`.`t1`.`a` in (1,2))/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 with tvc_0 as (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (dual) join `test`.`t1` where `test`.`t1`.`a` in (1,2))/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`_col_1` = `test`.`t1`.`a` explain extended select * from ( select * @@ -283,12 +312,11 @@ as tvc_0 ) ) as dr_table; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` # VIEW with IN-predicate create view v1 as select * @@ -316,20 +344,18 @@ a b 2 5 explain extended select * from v1; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`_col_1` = `test`.`t1`.`a` explain extended select * from v2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` drop view v1,v2; # subselect defined by derived table with IN-predicate select * from t1 @@ -382,11 +408,11 @@ as dr_table id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 MATERIALIZED eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 5 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0` join `test`.`t1`) where `test`.`t1`.`a` = 1 and `test`.`t1`.`a` = `tvc_0`.`_col_1` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0` join `test`.`t1`) where `test`.`t1`.`a` = 1 and `tvc_0`.`_col_1` = `test`.`t1`.`a` explain extended select * from t1 where a in ( @@ -407,11 +433,11 @@ as dr_table id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 MATERIALIZED eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 5 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0` join `test`.`t1`) where `test`.`t1`.`a` = 1 and `test`.`t1`.`a` = `tvc_0`.`1` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0` join `test`.`t1`) where `test`.`t1`.`a` = 1 and `tvc_0`.`1` = `test`.`t1`.`a` # derived table with IN-predicate and group by select * from ( @@ -444,13 +470,12 @@ where b in (3,5) group by b ) as dr_table; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL NULL NULL NULL NULL 12 100.00 -2 DERIVED t1 ALL NULL NULL NULL NULL 6 100.00 Using temporary; Using filesort -2 DERIVED eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY ALL NULL NULL NULL NULL 6 100.00 +2 DERIVED t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary; Using filesort +2 DERIVED eq_ref distinct_key distinct_key 4 test.t1.b 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `dr_table`.`max(a)` AS `max(a)`,`dr_table`.`b` AS `b` from (/* select#2 */ select max(`test`.`t1`.`a`) AS `max(a)`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (3),(5)) `tvc_0`) where 1 group by `test`.`t1`.`b`) `dr_table` +Note 1003 /* select#1 */ select `dr_table`.`max(a)` AS `max(a)`,`dr_table`.`b` AS `b` from (/* select#2 */ select max(`test`.`t1`.`a`) AS `max(a)`,`test`.`t1`.`b` AS `b` from (values (3),(5)) `tvc_0` join `test`.`t1` where `tvc_0`.`_col_1` = `test`.`t1`.`b` group by `test`.`t1`.`b`) `dr_table` explain extended select * from ( select max(a),b @@ -464,13 +489,12 @@ as tvc_0 group by b ) as dr_table; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL NULL NULL NULL NULL 12 100.00 -2 DERIVED t1 ALL NULL NULL NULL NULL 6 100.00 Using temporary; Using filesort -2 DERIVED eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY ALL NULL NULL NULL NULL 6 100.00 +2 DERIVED t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary; Using filesort +2 DERIVED eq_ref distinct_key distinct_key 4 test.t1.b 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `dr_table`.`max(a)` AS `max(a)`,`dr_table`.`b` AS `b` from (/* select#2 */ select max(`test`.`t1`.`a`) AS `max(a)`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (3),(5)) `tvc_0`) where 1 group by `test`.`t1`.`b`) `dr_table` +Note 1003 /* select#1 */ select `dr_table`.`max(a)` AS `max(a)`,`dr_table`.`b` AS `b` from (/* select#2 */ select max(`test`.`t1`.`a`) AS `max(a)`,`test`.`t1`.`b` AS `b` from (values (3),(5)) `tvc_0` join `test`.`t1` where `tvc_0`.`3` = `test`.`t1`.`b` group by `test`.`t1`.`b`) `dr_table` # prepare statement prepare stmt from "select * from t1 where a in (1,2)"; execute stmt; @@ -506,12 +530,11 @@ a b 4 yq explain extended select * from t3 where a in (1,4); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 100.00 -1 PRIMARY t3 ref idx idx 5 tvc_0._col_1 3 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t3 ALL idx NULL NULL NULL 28 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t3.a 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` semi join ((values (1),(4)) `tvc_0`) where `test`.`t3`.`a` = `tvc_0`.`_col_1` +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from (values (1),(4)) `tvc_0` join `test`.`t3` where `tvc_0`.`_col_1` = `test`.`t3`.`a` # use vectors in IN predeicate set @@in_predicate_conversion_threshold= 4; select * from t1 where (a,b) in ((1,2),(3,4)); @@ -519,14 +542,13 @@ a b 1 2 explain extended select * from t1 where (a,b) in ((1,2),(3,4)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.b 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1,2),(3,4)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1,2),(3,4)) `tvc_0` join `test`.`t1` where `tvc_0`.`_col_1` = `test`.`t1`.`a` and `tvc_0`.`_col_2` = `test`.`t1`.`b` set @@in_predicate_conversion_threshold= 2; -# trasformation works for the one IN predicate and doesn't work for the other +# transformation works for the one IN predicate and doesn't work for the other set @@in_predicate_conversion_threshold= 5; select * from t2 where (a,b) in ((1,2),(8,9)) and @@ -539,11 +561,10 @@ where (a,b) in ((1,2),(8,9)) and (a,c) in ((1,3),(8,0),(5,1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 3 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 test.t2.a,test.t2.c 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` semi join ((values (1,3),(8,0),(5,1)) `tvc_0`) where (`test`.`t2`.`a`,`test`.`t2`.`b`) in (((1,2)),((8,9))) +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from (values (1,3),(8,0),(5,1)) `tvc_0` join `test`.`t2` where `tvc_0`.`_col_1` = `test`.`t2`.`a` and `tvc_0`.`_col_2` = `test`.`t2`.`c` and (`test`.`t2`.`a`,`test`.`t2`.`b`) in (((1,2)),((8,9))) set @@in_predicate_conversion_threshold= 2; # # mdev-14281: conversion of NOT IN predicate into subquery predicate @@ -568,18 +589,18 @@ explain extended select * from t1 where (a,b) not in ((1,2),(8,9), (5,1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY index_subquery key0 key0 8 func,func 2 100.00 Using where; Full scan on NULL key +2 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 8 func,func 1 100.00 Using where; Full scan on NULL key 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<`test`.`t1`.`a`,`test`.`t1`.`b`>(((`test`.`t1`.`a`,`test`.`t1`.`b`),(((`test`.`t1`.`a`) in (temporary) on key0 where trigcond((`test`.`t1`.`a`) = `tvc_0`.`_col_1`) and trigcond((`test`.`t1`.`b`) = `tvc_0`.`_col_2`))))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<`test`.`t1`.`a`,`test`.`t1`.`b`>(((`test`.`t1`.`a`,`test`.`t1`.`b`),(((`test`.`t1`.`a`) in on distinct_key where trigcond((`test`.`t1`.`a`) = `tvc_0`.`_col_1`) and trigcond((`test`.`t1`.`b`) = `tvc_0`.`_col_2`))))) explain extended select * from t1 where (a,b) not in (select * from (values (1,2),(8,9), (5,1)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY index_subquery key0 key0 8 func,func 2 100.00 Using where; Full scan on NULL key +2 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 8 func,func 1 100.00 Using where; Full scan on NULL key 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<`test`.`t1`.`a`,`test`.`t1`.`b`>(((`test`.`t1`.`a`,`test`.`t1`.`b`),(((`test`.`t1`.`a`) in (temporary) on key0 where trigcond((`test`.`t1`.`a`) = `tvc_0`.`1`) and trigcond((`test`.`t1`.`b`) = `tvc_0`.`2`))))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<`test`.`t1`.`a`,`test`.`t1`.`b`>(((`test`.`t1`.`a`,`test`.`t1`.`b`),(((`test`.`t1`.`a`) in on distinct_key where trigcond((`test`.`t1`.`a`) = `tvc_0`.`1`) and trigcond((`test`.`t1`.`b`) = `tvc_0`.`2`))))) select * from t1 where b < 7 and (a,b) not in ((1,2),(8,9), (5,1)); a b @@ -590,10 +611,10 @@ explain extended select * from t1 where b < 7 and (a,b) not in ((1,2),(8,9), (5,1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY index_subquery key0 key0 8 func,func 2 100.00 Using where; Full scan on NULL key +2 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 8 func,func 1 100.00 Using where; Full scan on NULL key 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` < 7 and !<`test`.`t1`.`a`,`test`.`t1`.`b`>(((`test`.`t1`.`a`,`test`.`t1`.`b`),(((`test`.`t1`.`a`) in (temporary) on key0 where trigcond((`test`.`t1`.`a`) = `tvc_0`.`_col_1`) and trigcond((`test`.`t1`.`b`) = `tvc_0`.`_col_2`))))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` < 7 and !<`test`.`t1`.`a`,`test`.`t1`.`b`>(((`test`.`t1`.`a`,`test`.`t1`.`b`),(((`test`.`t1`.`a`) in on distinct_key where trigcond((`test`.`t1`.`a`) = `tvc_0`.`_col_1`) and trigcond((`test`.`t1`.`b`) = `tvc_0`.`_col_2`))))) select * from t2 where (a,c) not in ((1,2),(8,9), (5,1)); a b c @@ -606,10 +627,10 @@ explain extended select * from t2 where (a,c) not in ((1,2),(8,9), (5,1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY index_subquery key0 key0 8 func,func 2 100.00 Using where; Full scan on NULL key +2 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 8 func,func 1 100.00 Using where; Full scan on NULL key 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where !<`test`.`t2`.`a`,`test`.`t2`.`c`>(((`test`.`t2`.`a`,`test`.`t2`.`c`),(((`test`.`t2`.`a`) in (temporary) on key0 where trigcond((`test`.`t2`.`a`) = `tvc_0`.`_col_1`) and trigcond((`test`.`t2`.`c`) = `tvc_0`.`_col_2`))))) +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where !<`test`.`t2`.`a`,`test`.`t2`.`c`>(((`test`.`t2`.`a`,`test`.`t2`.`c`),(((`test`.`t2`.`a`) in on distinct_key where trigcond((`test`.`t2`.`a`) = `tvc_0`.`_col_1`) and trigcond((`test`.`t2`.`c`) = `tvc_0`.`_col_2`))))) drop table t1, t2, t3; set @@in_predicate_conversion_threshold= default; # diff --git a/mysql-test/main/opt_tvc.test b/mysql-test/main/opt_tvc.test index f8469f22aa1..89bede851eb 100644 --- a/mysql-test/main/opt_tvc.test +++ b/mysql-test/main/opt_tvc.test @@ -54,6 +54,23 @@ eval $optimized_query; eval explain extended $query; eval explain extended $optimized_query; + +let $query= select * from t1 where a in (1,2,2,2,3,4,5,6,7); + +let $optimized_query= +select * from t1 +where a in + ( + select * + from (values (1),(2),(2),(2),(2),(3),(4),(5),(6),(7)) as tvc_0 + ); + +eval $query; +eval $optimized_query; +eval explain extended $query; +eval explain extended $optimized_query; + + --echo # AND-condition with IN-predicates in WHERE-part let $query= @@ -276,7 +293,7 @@ eval $query; eval explain extended $query; set @@in_predicate_conversion_threshold= 2; ---echo # trasformation works for the one IN predicate and doesn't work for the other +--echo # transformation works for the one IN predicate and doesn't work for the other set @@in_predicate_conversion_threshold= 5; diff --git a/mysql-test/main/optimizer_costs.result b/mysql-test/main/optimizer_costs.result new file mode 100644 index 00000000000..49bfdc09a7c --- /dev/null +++ b/mysql-test/main/optimizer_costs.result @@ -0,0 +1,347 @@ +select table_name,engine from information_schema.tables where table_name="optimizer_costs"; +table_name engine +OPTIMIZER_COSTS MEMORY +show create table information_schema.optimizer_costs; +Table Create Table +OPTIMIZER_COSTS CREATE TEMPORARY TABLE `OPTIMIZER_COSTS` ( + `ENGINE` varchar(192) NOT NULL, + `OPTIMIZER_DISK_READ_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_INDEX_BLOCK_COPY_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_KEY_COMPARE_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_KEY_COPY_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_KEY_LOOKUP_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_KEY_NEXT_FIND_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_DISK_READ_RATIO` decimal(9,6) NOT NULL, + `OPTIMIZER_ROW_COPY_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_ROW_LOOKUP_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_ROW_NEXT_FIND_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_ROWID_COMPARE_COST` decimal(9,6) NOT NULL, + `OPTIMIZER_ROWID_COPY_COST` decimal(9,6) NOT NULL +) ENGINE=MEMORY DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci +select * from information_schema.optimizer_costs where engine in +("memory","innodb","aria","default") order by engine; +ENGINE Aria +OPTIMIZER_DISK_READ_COST 10.240000 +OPTIMIZER_INDEX_BLOCK_COPY_COST 0.035600 +OPTIMIZER_KEY_COMPARE_COST 0.011361 +OPTIMIZER_KEY_COPY_COST 0.015685 +OPTIMIZER_KEY_LOOKUP_COST 0.435777 +OPTIMIZER_KEY_NEXT_FIND_COST 0.082347 +OPTIMIZER_DISK_READ_RATIO 0.020000 +OPTIMIZER_ROW_COPY_COST 0.060866 +OPTIMIZER_ROW_LOOKUP_COST 0.130839 +OPTIMIZER_ROW_NEXT_FIND_COST 0.045916 +OPTIMIZER_ROWID_COMPARE_COST 0.002653 +OPTIMIZER_ROWID_COPY_COST 0.002653 +ENGINE default +OPTIMIZER_DISK_READ_COST 10.240000 +OPTIMIZER_INDEX_BLOCK_COPY_COST 0.035600 +OPTIMIZER_KEY_COMPARE_COST 0.011361 +OPTIMIZER_KEY_COPY_COST 0.015685 +OPTIMIZER_KEY_LOOKUP_COST 0.435777 +OPTIMIZER_KEY_NEXT_FIND_COST 0.082347 +OPTIMIZER_DISK_READ_RATIO 0.020000 +OPTIMIZER_ROW_COPY_COST 0.060866 +OPTIMIZER_ROW_LOOKUP_COST 0.130839 +OPTIMIZER_ROW_NEXT_FIND_COST 0.045916 +OPTIMIZER_ROWID_COMPARE_COST 0.002653 +OPTIMIZER_ROWID_COPY_COST 0.002653 +ENGINE InnoDB +OPTIMIZER_DISK_READ_COST 10.240000 +OPTIMIZER_INDEX_BLOCK_COPY_COST 0.035600 +OPTIMIZER_KEY_COMPARE_COST 0.011361 +OPTIMIZER_KEY_COPY_COST 0.015685 +OPTIMIZER_KEY_LOOKUP_COST 0.791120 +OPTIMIZER_KEY_NEXT_FIND_COST 0.099000 +OPTIMIZER_DISK_READ_RATIO 0.020000 +OPTIMIZER_ROW_COPY_COST 0.060870 +OPTIMIZER_ROW_LOOKUP_COST 0.765970 +OPTIMIZER_ROW_NEXT_FIND_COST 0.070130 +OPTIMIZER_ROWID_COMPARE_COST 0.002653 +OPTIMIZER_ROWID_COPY_COST 0.002653 +ENGINE MEMORY +OPTIMIZER_DISK_READ_COST 0.000000 +OPTIMIZER_INDEX_BLOCK_COPY_COST 0.000000 +OPTIMIZER_KEY_COMPARE_COST 0.011361 +OPTIMIZER_KEY_COPY_COST 0.000000 +OPTIMIZER_KEY_LOOKUP_COST 0.000000 +OPTIMIZER_KEY_NEXT_FIND_COST 0.000000 +OPTIMIZER_DISK_READ_RATIO 0.000000 +OPTIMIZER_ROW_COPY_COST 0.002334 +OPTIMIZER_ROW_LOOKUP_COST 0.000000 +OPTIMIZER_ROW_NEXT_FIND_COST 0.000000 +OPTIMIZER_ROWID_COMPARE_COST 0.002653 +OPTIMIZER_ROWID_COPY_COST 0.002653 +show variables like "optimizer%cost"; +Variable_name Value +optimizer_disk_read_cost 10.240000 +optimizer_index_block_copy_cost 0.035600 +optimizer_key_compare_cost 0.011361 +optimizer_key_copy_cost 0.015685 +optimizer_key_lookup_cost 0.435777 +optimizer_key_next_find_cost 0.082347 +optimizer_row_copy_cost 0.060866 +optimizer_row_lookup_cost 0.130839 +optimizer_row_next_find_cost 0.045916 +optimizer_rowid_compare_cost 0.002653 +optimizer_rowid_copy_cost 0.002653 +optimizer_scan_setup_cost 10.000000 +optimizer_where_cost 0.032000 +show variables like "optimizer_disk_read_ratio"; +Variable_name Value +optimizer_disk_read_ratio 0.020000 +# +# Test change some 'default' variables +# +SELECT @@optimizer_disk_read_ratio,@@optimizer_index_block_copy_cost; +@@optimizer_disk_read_ratio @@optimizer_index_block_copy_cost +0.020000 0.035600 +SET global optimizer_disk_read_ratio=0.8; +SET global optimizer_index_block_copy_cost=0.1; +SELECT @@optimizer_disk_read_ratio,@@optimizer_index_block_copy_cost; +@@optimizer_disk_read_ratio @@optimizer_index_block_copy_cost +0.800000 0.100000 +select optimizer_disk_read_ratio,optimizer_index_block_copy_cost from information_schema.optimizer_costs where engine='default'; +optimizer_disk_read_ratio optimizer_index_block_copy_cost +0.800000 0.100000 +SET global optimizer_disk_read_ratio=default; +SET global optimizer_index_block_copy_cost=default; +SELECT @@optimizer_disk_read_ratio,@@optimizer_index_block_copy_cost; +@@optimizer_disk_read_ratio @@optimizer_index_block_copy_cost +0.020000 0.035600 +# +# Test change some 'engine' variables +# +select @@MEMORY.optimizer_row_lookup_cost; +@@MEMORY.optimizer_row_lookup_cost +0.000000 +set @tmp=@@MEMORY.optimizer_row_lookup_cost; +set @@global.MEMORY.optimizer_row_lookup_cost=1; +select @@MEMORY.optimizer_row_lookup_cost; +@@MEMORY.optimizer_row_lookup_cost +1.000000 +set @@global.MEMORY.optimizer_row_lookup_cost=default; +select @@MEMORY.optimizer_row_lookup_cost; +@@MEMORY.optimizer_row_lookup_cost +0.130839 +set @@global.MEMORY.optimizer_row_lookup_cost=@tmp; +select @@MEMORY.optimizer_row_lookup_cost; +@@MEMORY.optimizer_row_lookup_cost +0.000000 +# +# Print variables with different syntaxes +# +SHOW VARIABLES like "optimizer_row_lookup_cost"; +Variable_name Value +optimizer_row_lookup_cost 0.130839 +SELECT @@optimizer_row_lookup_cost; +@@optimizer_row_lookup_cost +0.130839 +SELECT @@global.default.optimizer_row_lookup_cost; +@@global.default.optimizer_row_lookup_cost +0.130839 +SELECT @@global.default.`optimizer_row_lookup_cost`; +@@global.default.`optimizer_row_lookup_cost` +0.130839 +SELECT @@MEMORY.optimizer_row_lookup_cost; +@@MEMORY.optimizer_row_lookup_cost +0.000000 +SELECT @@memory.optimizer_row_lookup_cost; +@@memory.optimizer_row_lookup_cost +0.000000 +SELECT @@InnoDB.optimizer_row_lookup_cost; +@@InnoDB.optimizer_row_lookup_cost +0.765970 +# +# Accessing not existing cost +# +SELECT @@not_existing.optimizer_row_lookup_cost; +@@not_existing.optimizer_row_lookup_cost +0.130839 +SELECT @@NOT_existing.optimizer_row_lookup_cost; +@@NOT_existing.optimizer_row_lookup_cost +0.130839 +select engine from information_schema.optimizer_costs where engine like '%existing'; +engine +# +# Creating a new cost structure +# +SET global new_engine.optimizer_disk_read_cost=100; +select * from information_schema.optimizer_costs where engine like 'new_engine'; +ENGINE OPTIMIZER_DISK_READ_COST OPTIMIZER_INDEX_BLOCK_COPY_COST OPTIMIZER_KEY_COMPARE_COST OPTIMIZER_KEY_COPY_COST OPTIMIZER_KEY_LOOKUP_COST OPTIMIZER_KEY_NEXT_FIND_COST OPTIMIZER_DISK_READ_RATIO OPTIMIZER_ROW_COPY_COST OPTIMIZER_ROW_LOOKUP_COST OPTIMIZER_ROW_NEXT_FIND_COST OPTIMIZER_ROWID_COMPARE_COST OPTIMIZER_ROWID_COPY_COST +new_engine 100.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 +select @@new_engine.optimizer_disk_read_cost, @@new_engine.optimizer_row_copy_cost; +@@new_engine.optimizer_disk_read_cost @@new_engine.optimizer_row_copy_cost +100.000000 -1.000000 +# +# Errors +# +SELECT @@default.optimizer_disk_read_cost; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'default.optimizer_disk_read_cost' at line 1 +set global Aria.optimizer_disk_read_cost=NULL; +ERROR 42000: Incorrect argument type to variable 'optimizer_disk_read_cost' +set @tmp=@@Aria.optimizer_disk_read_cost; +SET global Aria.optimizer_disk_read_cost=-1; +Warnings: +Warning 1292 Truncated incorrect optimizer_disk_read_cost value: '-1' +select @@Aria.optimizer_disk_read_cost; +@@Aria.optimizer_disk_read_cost +0.000000 +SET global Aria.optimizer_disk_read_cost=200000; +Warnings: +Warning 1292 Truncated incorrect optimizer_disk_read_cost value: '200000' +select @@Aria.optimizer_disk_read_cost; +@@Aria.optimizer_disk_read_cost +10000.000000 +set global Aria.optimizer_disk_read_cost=@tmp; +select @@Aria.optimizer_disk_read_cost; +@@Aria.optimizer_disk_read_cost +10.240000 +# +# Test of cost of ref compared to table scan + join_cache +# +create or replace table t1 (p int primary key, a char(10)) engine=myisam; +create or replace table t2 (p int primary key, i int, a char(10), key k2(a)) engine=myisam; +insert into t2 select seq,seq,'a' from seq_1_to_512; +insert into t1 select seq,'a' from seq_1_to_4; +explain select count(*) from t1, t2 where t1.p = t2.i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 4 Using index +1 SIMPLE t2 ALL NULL NULL NULL NULL 512 Using where; Using join buffer (flat, BNL join) +insert into t1 select seq,'a' from seq_5_to_10; +explain select count(*) from t1, t2 where t1.p = t2.i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 512 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.i 1 Using index +drop table t1,t2; +# +# Test of optimizer_scan_setup_cost +# +create table t1 (p int primary key, a char(10)) engine=myisam; +create table t2 (p int primary key, i int, a char(10), key k1(i), key k2(a)) engine=myisam; +insert into t1 values (2, 'qqqq'), (11, 'yyyy'); +insert into t2 values (1, 2, 'qqqq'), (2, 2, 'pppp'), +(3, 2, 'yyyy'), (4, 3, 'zzzz'); +set @org_myisam_disk_read_ratio=@@myisam.optimizer_disk_read_ratio; +set @@optimizer_scan_setup_cost=10,@@global.myisam.optimizer_disk_read_ratio=0.2; +flush tables; +explain select sum(t2.p+length(t1.a)) from t1, t2 where t1.p = t2.i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 2 +1 SIMPLE t2 ref k1 k1 5 test.t1.p 1 +set @@optimizer_scan_setup_cost=0.0, @@global.myisam.optimizer_disk_read_ratio=0.0; +flush tables; +explain select sum(t2.p+length(t1.a)) from t1, t2 where t1.p = t2.i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 2 +1 SIMPLE t2 ALL k1 NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +set @@optimizer_scan_setup_cost=default,@@global.myisam.optimizer_disk_read_ratio=@org_myisam_disk_read_ratio; +flush tables; +drop table t1,t2; +# +# Test of group by optimization +# +set @@optimizer_scan_setup_cost=0; +CREATE TABLE t1 (id INT NOT NULL, a DATE, KEY(id,a)) engine=myisam; +INSERT INTO t1 values (1,'2001-01-01'),(1,'2001-01-02'), +(1,'2001-01-03'),(1,'2001-01-04'), +(2,'2001-01-01'),(2,'2001-01-02'), +(2,'2001-01-03'),(2,'2001-01-04'), +(3,'2001-01-01'),(3,'2001-01-02'), +(3,'2001-01-03'),(3,'2001-01-04'), +(4,'2001-01-01'),(4,'2001-01-02'), +(4,'2001-01-03'),(4,'2001-01-04'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL id 8 NULL 16 Using where; Using index +insert into t1 values (3,'2001-01-03'),(3,'2001-01-04'); +insert into t1 values (3,'2001-01-03'),(3,'2001-01-04'); +insert into t1 values (3,'2001-01-03'),(3,'2001-01-04'); +insert into t1 values (3,'2001-01-03'),(3,'2001-01-04'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL id 8 NULL 5 Using where; Using index for group-by +drop table t1; +set @@optimizer_scan_setup_cost=default; +# +# Test of straight join costs +# +create table t1 (l_orderkey int(11) NOT NULL, +l_partkey int(11) DEFAULT NULL, +l_suppkey int(11) DEFAULT NULL, +PRIMARY KEY (l_orderkey)) engine=aria; +insert into t1 select seq,seq,seq from seq_1_to_1000; +explain select straight_join count(*) from seq_1_to_10000,t1 where seq=l_orderkey; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_10000 index PRIMARY PRIMARY 8 NULL 10000 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.seq_1_to_10000.seq 1 Using where; Using index +show status like "last_query_cost"; +Variable_name Value +Last_query_cost 5.641229 +set @org_cost=@@aria.optimizer_key_next_find_cost; +set global aria.optimizer_key_next_find_cost=1000; +flush tables; +explain select count(*) from seq_1_to_10000,t1 where seq=l_orderkey; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_10000 index PRIMARY PRIMARY 8 NULL 10000 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.seq_1_to_10000.seq 1 Using where; Using index +show status like "last_query_cost"; +Variable_name Value +Last_query_cost 5.641229 +set global aria.optimizer_key_next_find_cost=@org_cost; +drop table t1; +# +# Testing distinct group optimization +# +create table t1 (a int, b int, key(a,b)); +insert into t1 select seq,seq from seq_1_to_1000; +explain select count(distinct a,b) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL a 10 NULL 1000 Using index for group-by (scanning) +explain select count(distinct a,b) from t1 where a>100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 10 NULL 901 Using where; Using index for group-by (scanning) +explain select count(distinct a,b) from t1 where a>800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 206 Using where; Using index +update t1 set a=mod(a,10); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +explain select count(distinct a,b) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL a 10 NULL 1000 Using index for group-by (scanning) +explain select count(distinct a,b) from t1 where a>1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 10 NULL 788 Using where; Using index for group-by (scanning) +explain select count(distinct a,b) from t1 where a>8; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 109 Using where; Using index +update t1 set b=mod(b,2); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +explain select count(distinct a,b) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL a 10 NULL 11 Using index for group-by +explain select count(distinct a,b) from t1 where a>1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 10 NULL 9 Using where; Using index for group-by +explain select count(distinct a,b) from t1 where a>8; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 10 NULL 1 Using where; Using index for group-by +drop table t1; +# +# cleanup +# +Start_engines: 9 End_engines: 10 diff --git a/mysql-test/main/optimizer_costs.test b/mysql-test/main/optimizer_costs.test new file mode 100644 index 00000000000..13ce927fb26 --- /dev/null +++ b/mysql-test/main/optimizer_costs.test @@ -0,0 +1,187 @@ +# +# Test of optimizer_costs +# +--source include/have_innodb.inc +--source include/have_sequence.inc + +select table_name,engine from information_schema.tables where table_name="optimizer_costs"; +show create table information_schema.optimizer_costs; +let $start_engines=`select count(*) from information_schema.optimizer_costs`; +--vertical_results +select * from information_schema.optimizer_costs where engine in +("memory","innodb","aria","default") order by engine; +--horizontal_results +show variables like "optimizer%cost"; +show variables like "optimizer_disk_read_ratio"; + +--echo # +--echo # Test change some 'default' variables +--echo # +SELECT @@optimizer_disk_read_ratio,@@optimizer_index_block_copy_cost; +SET global optimizer_disk_read_ratio=0.8; +SET global optimizer_index_block_copy_cost=0.1; +SELECT @@optimizer_disk_read_ratio,@@optimizer_index_block_copy_cost; +select optimizer_disk_read_ratio,optimizer_index_block_copy_cost from information_schema.optimizer_costs where engine='default'; +SET global optimizer_disk_read_ratio=default; +SET global optimizer_index_block_copy_cost=default; +SELECT @@optimizer_disk_read_ratio,@@optimizer_index_block_copy_cost; + +--echo # +--echo # Test change some 'engine' variables +--echo # +select @@MEMORY.optimizer_row_lookup_cost; +set @tmp=@@MEMORY.optimizer_row_lookup_cost; +set @@global.MEMORY.optimizer_row_lookup_cost=1; +select @@MEMORY.optimizer_row_lookup_cost; +set @@global.MEMORY.optimizer_row_lookup_cost=default; +select @@MEMORY.optimizer_row_lookup_cost; +set @@global.MEMORY.optimizer_row_lookup_cost=@tmp; +select @@MEMORY.optimizer_row_lookup_cost; + +--echo # +--echo # Print variables with different syntaxes +--echo # +SHOW VARIABLES like "optimizer_row_lookup_cost"; +SELECT @@optimizer_row_lookup_cost; +SELECT @@global.default.optimizer_row_lookup_cost; +SELECT @@global.default.`optimizer_row_lookup_cost`; +SELECT @@MEMORY.optimizer_row_lookup_cost; +SELECT @@memory.optimizer_row_lookup_cost; +SELECT @@InnoDB.optimizer_row_lookup_cost; + +--echo # +--echo # Accessing not existing cost +--echo # +SELECT @@not_existing.optimizer_row_lookup_cost; +SELECT @@NOT_existing.optimizer_row_lookup_cost; +select engine from information_schema.optimizer_costs where engine like '%existing'; + +--echo # +--echo # Creating a new cost structure +--echo # +SET global new_engine.optimizer_disk_read_cost=100; +select * from information_schema.optimizer_costs where engine like 'new_engine'; +select @@new_engine.optimizer_disk_read_cost, @@new_engine.optimizer_row_copy_cost; + +--echo # +--echo # Errors +--echo # +--error ER_PARSE_ERROR +SELECT @@default.optimizer_disk_read_cost; +--error ER_WRONG_TYPE_FOR_VAR +set global Aria.optimizer_disk_read_cost=NULL; + +set @tmp=@@Aria.optimizer_disk_read_cost; +SET global Aria.optimizer_disk_read_cost=-1; +select @@Aria.optimizer_disk_read_cost; +SET global Aria.optimizer_disk_read_cost=200000; +select @@Aria.optimizer_disk_read_cost; +set global Aria.optimizer_disk_read_cost=@tmp; +select @@Aria.optimizer_disk_read_cost; + +--echo # +--echo # Test of cost of ref compared to table scan + join_cache +--echo # + +create or replace table t1 (p int primary key, a char(10)) engine=myisam; +create or replace table t2 (p int primary key, i int, a char(10), key k2(a)) engine=myisam; +insert into t2 select seq,seq,'a' from seq_1_to_512; + +insert into t1 select seq,'a' from seq_1_to_4; +explain select count(*) from t1, t2 where t1.p = t2.i; +insert into t1 select seq,'a' from seq_5_to_10; +explain select count(*) from t1, t2 where t1.p = t2.i; + +drop table t1,t2; + +--echo # +--echo # Test of optimizer_scan_setup_cost +--echo # + +create table t1 (p int primary key, a char(10)) engine=myisam; +create table t2 (p int primary key, i int, a char(10), key k1(i), key k2(a)) engine=myisam; +insert into t1 values (2, 'qqqq'), (11, 'yyyy'); +insert into t2 values (1, 2, 'qqqq'), (2, 2, 'pppp'), + (3, 2, 'yyyy'), (4, 3, 'zzzz'); +set @org_myisam_disk_read_ratio=@@myisam.optimizer_disk_read_ratio; +set @@optimizer_scan_setup_cost=10,@@global.myisam.optimizer_disk_read_ratio=0.2; +flush tables; +explain select sum(t2.p+length(t1.a)) from t1, t2 where t1.p = t2.i; +set @@optimizer_scan_setup_cost=0.0, @@global.myisam.optimizer_disk_read_ratio=0.0; +flush tables; +explain select sum(t2.p+length(t1.a)) from t1, t2 where t1.p = t2.i; +set @@optimizer_scan_setup_cost=default,@@global.myisam.optimizer_disk_read_ratio=@org_myisam_disk_read_ratio; +flush tables; +drop table t1,t2; + +--echo # +--echo # Test of group by optimization +--echo # + +set @@optimizer_scan_setup_cost=0; +CREATE TABLE t1 (id INT NOT NULL, a DATE, KEY(id,a)) engine=myisam; +INSERT INTO t1 values (1,'2001-01-01'),(1,'2001-01-02'), +(1,'2001-01-03'),(1,'2001-01-04'), +(2,'2001-01-01'),(2,'2001-01-02'), +(2,'2001-01-03'),(2,'2001-01-04'), +(3,'2001-01-01'),(3,'2001-01-02'), +(3,'2001-01-03'),(3,'2001-01-04'), +(4,'2001-01-01'),(4,'2001-01-02'), +(4,'2001-01-03'),(4,'2001-01-04'); +analyze table t1; +EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id; +insert into t1 values (3,'2001-01-03'),(3,'2001-01-04'); +insert into t1 values (3,'2001-01-03'),(3,'2001-01-04'); +insert into t1 values (3,'2001-01-03'),(3,'2001-01-04'); +insert into t1 values (3,'2001-01-03'),(3,'2001-01-04'); +analyze table t1; +EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id; +drop table t1; +set @@optimizer_scan_setup_cost=default; + +--echo # +--echo # Test of straight join costs +--echo # +create table t1 (l_orderkey int(11) NOT NULL, + l_partkey int(11) DEFAULT NULL, + l_suppkey int(11) DEFAULT NULL, + PRIMARY KEY (l_orderkey)) engine=aria; +insert into t1 select seq,seq,seq from seq_1_to_1000; +explain select straight_join count(*) from seq_1_to_10000,t1 where seq=l_orderkey; +show status like "last_query_cost"; +set @org_cost=@@aria.optimizer_key_next_find_cost; +# Set cost for t1 high so that we cannot use it for index scans +set global aria.optimizer_key_next_find_cost=1000; +flush tables; +explain select count(*) from seq_1_to_10000,t1 where seq=l_orderkey; +show status like "last_query_cost"; +set global aria.optimizer_key_next_find_cost=@org_cost; +drop table t1; + +--echo # +--echo # Testing distinct group optimization +--echo # + +create table t1 (a int, b int, key(a,b)); +insert into t1 select seq,seq from seq_1_to_1000; +explain select count(distinct a,b) from t1; +explain select count(distinct a,b) from t1 where a>100; +explain select count(distinct a,b) from t1 where a>800; +update t1 set a=mod(a,10); +analyze table t1; +explain select count(distinct a,b) from t1; +explain select count(distinct a,b) from t1 where a>1; +explain select count(distinct a,b) from t1 where a>8; +update t1 set b=mod(b,2); +analyze table t1; +explain select count(distinct a,b) from t1; +explain select count(distinct a,b) from t1 where a>1; +explain select count(distinct a,b) from t1 where a>8; +drop table t1; + +--echo # +--echo # cleanup +--echo # + +let $end_engines=`select count(*) from information_schema.optimizer_costs`; +--echo Start_engines: $start_engines End_engines: $end_engines diff --git a/mysql-test/main/optimizer_costs2.opt b/mysql-test/main/optimizer_costs2.opt new file mode 100644 index 00000000000..718ccafc05e --- /dev/null +++ b/mysql-test/main/optimizer_costs2.opt @@ -0,0 +1 @@ +--optimizer_disk_read_ratio=0.9 --MEMORY.optimizer_disk_read_ratio=0.1 --memory.optimizer_disk_read_ratio=0.3 --memory.optimizer_row_lookup_cost=0.8 diff --git a/mysql-test/main/optimizer_costs2.result b/mysql-test/main/optimizer_costs2.result new file mode 100644 index 00000000000..688dcb51110 --- /dev/null +++ b/mysql-test/main/optimizer_costs2.result @@ -0,0 +1,8 @@ +select engine,optimizer_disk_read_ratio from information_schema.optimizer_costs where engine in ("memory","aria","default"); +engine optimizer_disk_read_ratio +default 0.900000 +MEMORY 0.300000 +Aria 0.900000 +select @@memory.optimizer_row_lookup_cost; +@@memory.optimizer_row_lookup_cost +0.800000 diff --git a/mysql-test/main/optimizer_costs2.test b/mysql-test/main/optimizer_costs2.test new file mode 100644 index 00000000000..0445ce523cd --- /dev/null +++ b/mysql-test/main/optimizer_costs2.test @@ -0,0 +1,6 @@ +# +# Check default optimizer_cost_arguments +# + +select engine,optimizer_disk_read_ratio from information_schema.optimizer_costs where engine in ("memory","aria","default"); +select @@memory.optimizer_row_lookup_cost; diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result index 1311f42dac2..96f5d9a49c3 100644 --- a/mysql-test/main/order_by.result +++ b/mysql-test/main/order_by.result @@ -1192,7 +1192,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index k2 k3 5 NULL 111 Using where EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 4000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index k2 k3 5 NULL 22318 Using where +1 SIMPLE t2 range k2 k2 5 NULL 7341 Using index condition; Using filesort +EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 6000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL k2 NULL NULL NULL 40960 Using where; Using filesort EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 10 AND 12 ORDER BY c3 LIMIT 20; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index k2 k3 5 NULL 73 Using where @@ -1221,6 +1224,10 @@ id c3 176 14 186 14 196 14 +ALTER TABLE t2 DROP INDEX k3, ADD INDEX k3 (c3,c2); +EXPLAIN SELECT c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 4000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index k2 k3 10 NULL 22318 Using where; Using index DROP TABLE t1,t2; CREATE TABLE t1 ( a INT, @@ -1548,6 +1555,56 @@ UNIQUE KEY a_c (a,c), KEY (a)); INSERT INTO t1 VALUES (1, 10), (2, NULL); # Must use ref-or-null on the a_c index +ANALYZE FORMAT=JSON +SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "read_sorted_file": { + "r_rows": 1, + "filesort": { + "sort_key": "t1.c", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "r_used_priority_queue": false, + "r_output_rows": 1, + "r_buffer_size": "REPLACED", + "r_sort_mode": "sort_key,addon_fields", + "table": { + "table_name": "t1", + "access_type": "ref_or_null", + "possible_keys": ["a_c", "a"], + "key": "a_c", + "key_length": "10", + "used_key_parts": ["a", "c"], + "ref": ["const", "const"], + "loops": 1, + "r_loops": 1, + "rows": 2, + "r_rows": 1, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 50, + "r_filtered": 100, + "attached_condition": "t1.c = 10 or t1.c is null", + "using_index": true + } + } + } + } + ] + } +} EXPLAIN SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; id select_type table type possible_keys key key_len ref rows Extra @@ -2976,17 +3033,17 @@ EXPLAIN SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.a=t2.a ORDER BY t1.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL 8 Using index -1 SIMPLE t2 ref i_a i_a 5 test.t1.a 2 Using index +1 SIMPLE t2 ref i_a i_a 5 test.t1.a 1 Using index EXPLAIN SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.a=t2.a ORDER BY t1.a LIMIT 8; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using index -1 SIMPLE t2 ref i_a i_a 5 test.t1.a 2 Using index +1 SIMPLE t1 index NULL PRIMARY 4 NULL 6 Using index +1 SIMPLE t2 ref i_a i_a 5 test.t1.a 1 Using index EXPLAIN SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.a=t2.a ORDER BY t1.a LIMIT 100; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL 8 Using index -1 SIMPLE t2 ref i_a i_a 5 test.t1.a 2 Using index +1 SIMPLE t2 ref i_a i_a 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-4974 memory leak in 5.5.32-MariaDB-1~wheezy-log @@ -3065,7 +3122,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 1 PRIMARY t3a ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary -1 PRIMARY t3b ref f3_key f3_key 6 test.t3a.f3 1 100.00 Using where; End temporary +1 PRIMARY t3b ref f3_key f3_key 6 test.t3a.f3 1 41.67 Using where; End temporary Warnings: Note 1003 select concat('foo',`test`.`t2`.`f2`) AS `field` from `test`.`t2` semi join ((`test`.`t3` `t3a` join `test`.`t3` `t3b`)) where `test`.`t3a`.`f3` < 'foo' or `test`.`t3b`.`f3` <> 'foo' order by concat('foo',`test`.`t2`.`f2`) DROP TABLE t1,t2,t3; @@ -3119,7 +3176,7 @@ id select_type table type possible_keys key key_len ref rows Extra # See above query EXPLAIN SELECT id1 FROM t2 WHERE id2=1 AND id3=1 ORDER BY date DESC LIMIT 0,4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range id_23_date,id_234_date id_23_date 2 NULL 8 Using where +1 SIMPLE t2 ref id_23_date,id_234_date id_23_date 2 const,const 8 Using where drop table t1,t2; # # MDEV-8989: ORDER BY optimizer ignores equality propagation @@ -3188,13 +3245,13 @@ explain select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b from t2, t3 where t2.a=t3.a order by t2.a limit 25; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL a NULL NULL NULL 200 Using where; Using filesort +1 SIMPLE t2 index a a 5 NULL 25 Using where 1 SIMPLE t3 ref a a 5 test.t2.a 1 explain select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b from t2, t3 where t2.a=t3.a order by t3.a limit 25; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL a NULL NULL NULL 200 Using where; Using filesort +1 SIMPLE t2 index a a 5 NULL 25 Using where 1 SIMPLE t3 ref a a 5 test.t2.a 1 select t2.pk,t2.a,t2.b,t3.pk,t3.a,t3.b from t2, t3 where t2.a=t3.a order by t2.a limit 25; @@ -3401,6 +3458,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -3412,16 +3470,17 @@ ANALYZE "r_loops": 1, "r_total_time_ms": "REPLACED", "r_limit": 5, - "r_used_priority_queue": false, - "r_output_rows": 100, - "r_buffer_size": "REPLACED", - "r_sort_mode": "sort_key,packed_addon_fields", + "r_used_priority_queue": true, + "r_output_rows": 6, + "r_sort_mode": "sort_key,rowid", "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 100, "r_rows": 100, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3453,7 +3512,7 @@ CREATE TABLE t2 SELECT * FROM t1; EXPLAIN SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FROM t2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 -2 DEPENDENT SUBQUERY t1 index PRIMARY b 5 NULL 1 Using where +2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.t2.b 1 Using where SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FROM t2; c 1 @@ -3501,11 +3560,10 @@ WHERE books.library_id = 8663 AND books.scheduled_for_removal=0 ) ORDER BY wings.id; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 100.00 Using filesort -1 PRIMARY wings eq_ref PRIMARY PRIMARY 4 test.books.wings_id 1 100.00 -2 MATERIALIZED books ref library_idx library_idx 4 const 2 100.00 Using where +1 PRIMARY wings ALL PRIMARY NULL NULL NULL 2 100.00 Using filesort +1 PRIMARY books ref library_idx library_idx 4 const 2 50.00 Using where; FirstMatch(wings) Warnings: -Note 1003 select `test`.`wings`.`id` AS `wing_id`,`test`.`wings`.`department_id` AS `department_id` from `test`.`wings` semi join (`test`.`books`) where `test`.`books`.`library_id` = 8663 and `test`.`books`.`scheduled_for_removal` = 0 and `test`.`wings`.`id` = `test`.`books`.`wings_id` order by `test`.`wings`.`id` +Note 1003 select `test`.`wings`.`id` AS `wing_id`,`test`.`wings`.`department_id` AS `department_id` from `test`.`wings` semi join (`test`.`books`) where `test`.`books`.`library_id` = 8663 and `test`.`books`.`scheduled_for_removal` = 0 and `test`.`books`.`wings_id` = `test`.`wings`.`id` order by `test`.`wings`.`id` set optimizer_switch= @save_optimizer_switch; DROP TABLE books, wings; # @@ -3637,8 +3695,8 @@ WHERE t2.key1 = t1.a and t2.key1 IS NOT NULL ORDER BY t2.key2 ASC -LIMIT 1) -from t1; +LIMIT 1) as "con" + from t1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 10 2 DEPENDENT SUBQUERY t2 ref key1 key1 5 test.t1.a 10 Using index condition; Using where; Using filesort @@ -3649,25 +3707,19 @@ WHERE t2.key1 = t1.a and t2.key1 IS NOT NULL ORDER BY t2.key2 ASC -LIMIT 1) -from t1; -(SELECT concat(id, '-', key1, '-', col1) -FROM t2 -WHERE -t2.key1 = t1.a and t2.key1 IS NOT NULL -ORDER BY -t2.key2 ASC -LIMIT 1) -900-0-123456 -901-1-123456 -902-2-123456 -903-3-123456 -904-4-123456 -905-5-123456 -906-6-123456 -907-7-123456 -908-8-123456 -909-9-123456 +LIMIT 1) as "con" + from t1; +con +100-0-123456 +101-1-123456 +102-2-123456 +103-3-123456 +104-4-123456 +105-5-123456 +106-6-123456 +107-7-123456 +108-8-123456 +109-9-123456 drop table t1,t2; # End of 10.3 tests # @@ -3758,6 +3810,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -3775,9 +3828,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 100, "r_rows": 100, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3924,6 +3979,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -3941,9 +3997,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 5, "r_rows": 5, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3973,6 +4031,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -3990,9 +4049,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 6, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4028,6 +4089,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -4045,9 +4107,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 6, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4097,6 +4161,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -4114,9 +4179,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4279,6 +4346,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -4286,9 +4354,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 50, "r_rows": 50, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4303,6 +4373,7 @@ ANALYZE "r_hit_ratio": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 50, "r_total_time_ms": "REPLACED", "filesort": { @@ -4319,9 +4390,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 50, "rows": 50, "r_rows": 50, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -4400,7 +4473,8 @@ CREATE TABLE t1 (a INT, b int, primary key(a)); CREATE TABLE t2 (a INT, b INT); INSERT INTO t1 (a,b) VALUES (58,1),(96,2),(273,3),(23,4),(231,5),(525,6), (2354,7),(321421,3),(535,2),(4535,3); -INSERT INTO t2 (a,b) VALUES (58,3),(96,3),(273,3); +INSERT INTO t2 (a,b) VALUES (58,3),(96,3),(273,3),(1000,1000),(2000,2000),(3000,3000); +INSERT INTO t2 select seq,seq from seq_10_to_100; # Join order should have the SJM scan table as the first table for both # the queries with GROUP BY and ORDER BY clause. EXPLAIN SELECT t1.a @@ -4408,9 +4482,9 @@ FROM t1 WHERE t1.a IN (SELECT a FROM t2 WHERE b=3) ORDER BY t1.a DESC; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 3 Using filesort -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using index -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 10 Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 97 Using where EXPLAIN FORMAT=JSON SELECT t1.a FROM t1 WHERE t1.a IN (SELECT a FROM t2 WHERE b=3) @@ -4419,51 +4493,54 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ - { - "read_sorted_file": { - "filesort": { - "sort_key": "t1.a desc", - "table": { - "table_name": "", - "access_type": "ALL", - "possible_keys": ["distinct_key"], - "rows": 3, - "filtered": 100, - "materialized": { - "unique": 1, - "query_block": { - "select_id": 2, - "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "ALL", - "rows": 3, - "filtered": 100, - "attached_condition": "t2.b = 3 and t2.a is not null" - } - } - ] - } - } - } - } - } - }, { "table": { "table_name": "t1", - "access_type": "eq_ref", + "access_type": "index", "possible_keys": ["PRIMARY"], "key": "PRIMARY", "key_length": "4", "used_key_parts": ["a"], - "ref": ["test.t2.a"], - "rows": 1, + "loops": 1, + "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "using_index": true } + }, + { + "table": { + "table_name": "", + "access_type": "eq_ref", + "possible_keys": ["distinct_key"], + "key": "distinct_key", + "key_length": "4", + "used_key_parts": ["a"], + "ref": ["func"], + "rows": 1, + "filtered": 100, + "materialized": { + "unique": 1, + "query_block": { + "select_id": 2, + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "ALL", + "loops": 1, + "rows": 97, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t2.b = 3" + } + } + ] + } + } + } } ] } @@ -4481,9 +4558,9 @@ FROM t1 WHERE t1.a IN (SELECT a FROM t2 WHERE b=3) GROUP BY t1.a DESC; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 3 Using filesort -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 10 Using filesort +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 97 Using where EXPLAIN FORMAT=JSON SELECT t1.a, group_concat(t1.b) FROM t1 WHERE t1.a IN (SELECT a FROM t2 WHERE b=3) @@ -4492,49 +4569,54 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { "filesort": { "sort_key": "t1.a desc", "table": { - "table_name": "", + "table_name": "t1", "access_type": "ALL", - "possible_keys": ["distinct_key"], - "rows": 3, - "filtered": 100, - "materialized": { - "unique": 1, - "query_block": { - "select_id": 2, - "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "ALL", - "rows": 3, - "filtered": 100, - "attached_condition": "t2.b = 3 and t2.a is not null" - } - } - ] - } - } + "possible_keys": ["PRIMARY"], + "loops": 1, + "rows": 10, + "cost": "COST_REPLACED", + "filtered": 100 } } } }, { "table": { - "table_name": "t1", + "table_name": "", "access_type": "eq_ref", - "possible_keys": ["PRIMARY"], - "key": "PRIMARY", + "possible_keys": ["distinct_key"], + "key": "distinct_key", "key_length": "4", "used_key_parts": ["a"], - "ref": ["test.t2.a"], + "ref": ["func"], "rows": 1, - "filtered": 100 + "filtered": 100, + "materialized": { + "unique": 1, + "query_block": { + "select_id": 2, + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "ALL", + "loops": 1, + "rows": 97, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t2.b = 3" + } + } + ] + } + } } } ] diff --git a/mysql-test/main/order_by.test b/mysql-test/main/order_by.test index 1cd9efa2710..a292e468ef2 100644 --- a/mysql-test/main/order_by.test +++ b/mysql-test/main/order_by.test @@ -9,6 +9,7 @@ --source include/no_view_protocol.inc call mtr.add_suppression("Sort aborted.*"); +--source include/have_sequence.inc call mtr.add_suppression("Out of sort memory; increase server sort buffer size"); --source include/have_sequence.inc @@ -798,11 +799,16 @@ INSERT INTO t2 SELECT * FROM t1 ORDER BY id; EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20; EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 4000; +EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 6000; EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 10 AND 12 ORDER BY c3 LIMIT 20; EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000; SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20; +# Show that order by optimization takes into account index only scans +ALTER TABLE t2 DROP INDEX k3, ADD INDEX k3 (c3,c2); +EXPLAIN SELECT c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 4000; + DROP TABLE t1,t2; # @@ -907,8 +913,12 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES (1, 10), (2, NULL); --echo # Must use ref-or-null on the a_c index +--source include/analyze-format.inc +ANALYZE FORMAT=JSON +SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; EXPLAIN SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; + --echo # Must return 1 row SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; @@ -2388,7 +2398,7 @@ let $query= select t2.key1 = t1.a and t2.key1 IS NOT NULL ORDER BY t2.key2 ASC - LIMIT 1) + LIMIT 1) as "con" from t1; --echo # here type should show ref not index @@ -2671,8 +2681,8 @@ CREATE TABLE t2 (a INT, b INT); INSERT INTO t1 (a,b) VALUES (58,1),(96,2),(273,3),(23,4),(231,5),(525,6), (2354,7),(321421,3),(535,2),(4535,3); -INSERT INTO t2 (a,b) VALUES (58,3),(96,3),(273,3); - +INSERT INTO t2 (a,b) VALUES (58,3),(96,3),(273,3),(1000,1000),(2000,2000),(3000,3000); +INSERT INTO t2 select seq,seq from seq_10_to_100; --echo # Join order should have the SJM scan table as the first table for both --echo # the queries with GROUP BY and ORDER BY clause. @@ -2682,6 +2692,7 @@ let $query= SELECT t1.a ORDER BY t1.a DESC; eval EXPLAIN $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; eval $query; @@ -2691,6 +2702,7 @@ let $query= SELECT t1.a, group_concat(t1.b) GROUP BY t1.a DESC; eval EXPLAIN $query; +--source include/explain-no-costs.inc eval EXPLAIN FORMAT=JSON $query; eval $query; DROP TABLE t1, t2; diff --git a/mysql-test/main/order_by_innodb.result b/mysql-test/main/order_by_innodb.result index 741084c8a6c..ad4acad3319 100644 --- a/mysql-test/main/order_by_innodb.result +++ b/mysql-test/main/order_by_innodb.result @@ -53,17 +53,29 @@ KEY a_c (a,c), KEY a_b (a,b) ) ENGINE=InnoDB; insert into t1 select A.a , B.a, C.a from t0 A, t0 B, t0 C; +select count(*) from t1; +count(*) +1000 +select count(*) from t1 where a=1; +count(*) +200 +select count(*) from t1 where a=1 and c=2; +count(*) +20 # should use ref access explain select a,b,c from t1 where a=1 and c=2 order by b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a_c,a_b a_c 10 const,const 20 Using where; Using filesort -# both should use range access +# all should use range access +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 ref a_c,a_b a_c 10 const,const 20 Using where; Using filesort +explain select a,b,c from t1 where a=1 and c=2 order by b limit 300; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a_c,a_b a_c 10 const,const 20 Using where; Using filesort explain select a,b,c from t1 where a=1 and c=2 order by b limit 1000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a_c,a_b a_b 5 NULL 200 Using where -explain select a,b,c from t1 where a=1 and c=2 order by b limit 2000; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a_c,a_b a_b 5 NULL 200 Using where +1 SIMPLE t1 ref a_c,a_b a_c 10 const,const 20 Using where; Using filesort drop table t1,t0; # Start of 10.2 tests # @@ -244,8 +256,8 @@ d1 > '2019-02-06 00:00:00' dd.d1, dd.d2, dd.id limit 1 ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index -1 PRIMARY t2 eq_ref PRIMARY,id2 PRIMARY 4 func # Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL # +1 PRIMARY t2 eq_ref PRIMARY,id2 id2 8 test.t1.id,func # Using where; Using index 2 DEPENDENT SUBQUERY dd range id2,for_latest_sort for_latest_sort 6 NULL # Using where drop table t1,t2,t3; # End of 10.2 tests diff --git a/mysql-test/main/order_by_innodb.test b/mysql-test/main/order_by_innodb.test index bdaef56672f..acce96c7603 100644 --- a/mysql-test/main/order_by_innodb.test +++ b/mysql-test/main/order_by_innodb.test @@ -66,13 +66,17 @@ KEY a_c (a,c), KEY a_b (a,b) ) ENGINE=InnoDB; insert into t1 select A.a , B.a, C.a from t0 A, t0 B, t0 C; +select count(*) from t1; +select count(*) from t1 where a=1; +select count(*) from t1 where a=1 and c=2; --echo # should use ref access explain select a,b,c from t1 where a=1 and c=2 order by b; ---echo # both should use range access +--echo # all should use range access +explain select a,b,c from t1 where a=1 and c=2 order by b limit 10; +explain select a,b,c from t1 where a=1 and c=2 order by b limit 300; explain select a,b,c from t1 where a=1 and c=2 order by b limit 1000; -explain select a,b,c from t1 where a=1 and c=2 order by b limit 2000; drop table t1,t0; --echo # Start of 10.2 tests diff --git a/mysql-test/main/order_by_pack_big.result b/mysql-test/main/order_by_pack_big.result index 6b33d7d8202..09b4b729de1 100644 --- a/mysql-test/main/order_by_pack_big.result +++ b/mysql-test/main/order_by_pack_big.result @@ -94,6 +94,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -111,9 +112,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10000, "r_rows": 10000, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -258,6 +261,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -276,9 +280,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10000, "r_rows": 10000, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -420,6 +426,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -437,9 +444,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10000, "r_rows": 10000, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -476,6 +485,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -493,9 +503,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10000, "r_rows": 10000, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, diff --git a/mysql-test/main/order_by_sortkey.result b/mysql-test/main/order_by_sortkey.result index c1d9609eb47..6970568882f 100644 --- a/mysql-test/main/order_by_sortkey.result +++ b/mysql-test/main/order_by_sortkey.result @@ -40,6 +40,9 @@ INSERT INTO tmp SELECT f1,f2 FROM t1; INSERT INTO t1(f1,f2) SELECT * FROM tmp; INSERT INTO tmp SELECT f1,f2 FROM t1; INSERT INTO t1(f1,f2) SELECT * FROM tmp; +select count(*) from t1; +count(*) +87700 set sort_buffer_size= 32768; FLUSH STATUS; SHOW SESSION STATUS LIKE 'Sort%'; @@ -49,6 +52,9 @@ Sort_priority_queue_sorts 0 Sort_range 0 Sort_rows 0 Sort_scan 0 +explain SELECT * FROM t1 ORDER BY f2 LIMIT 100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 87700 Using filesort SELECT * FROM t1 ORDER BY f2 LIMIT 100; f0 f1 f2 1 0 0 @@ -151,11 +157,24 @@ f0 f1 f2 9701 0 0 9801 0 0 9901 0 0 -SHOW SESSION STATUS LIKE 'Sort%'; -Variable_name Value -Sort_merge_passes 0 -Sort_priority_queue_sorts 1 -Sort_range 0 -Sort_rows 100 -Sort_scan 1 -DROP TABLE t1, tmp; +create table t2 +select * from information_schema.SESSION_STATUS +where +variable_name like 'handler_read_rnd%' or +variable_name like 'Sort%'; +select * from t2 where variable_name like 'Sort%'; +VARIABLE_NAME VARIABLE_VALUE +SORT_MERGE_PASSES 0 +SORT_PRIORITY_QUEUE_SORTS 1 +SORT_RANGE 0 +SORT_ROWS 100 +SORT_SCAN 1 +select * from t2 where variable_name='HANDLER_READ_RND'; +VARIABLE_NAME VARIABLE_VALUE +HANDLER_READ_RND 100 +select +if(variable_value in (87701, 87802), 'OK', 'FAIL') as RES +from t2 where variable_name='HANDLER_READ_RND_NEXT'; +RES +OK +DROP TABLE t1, tmp, t2; diff --git a/mysql-test/main/order_by_sortkey.test b/mysql-test/main/order_by_sortkey.test index 43de028496e..8c7ae4b192e 100644 --- a/mysql-test/main/order_by_sortkey.test +++ b/mysql-test/main/order_by_sortkey.test @@ -50,6 +50,7 @@ INSERT INTO tmp SELECT f1,f2 FROM t1; INSERT INTO t1(f1,f2) SELECT * FROM tmp; INSERT INTO tmp SELECT f1,f2 FROM t1; INSERT INTO t1(f1,f2) SELECT * FROM tmp; +select count(*) from t1; # Test when only sortkeys fits to memory set sort_buffer_size= 32768; @@ -57,8 +58,24 @@ set sort_buffer_size= 32768; FLUSH STATUS; SHOW SESSION STATUS LIKE 'Sort%'; +explain SELECT * FROM t1 ORDER BY f2 LIMIT 100; SELECT * FROM t1 ORDER BY f2 LIMIT 100; -SHOW SESSION STATUS LIKE 'Sort%'; +create table t2 +select * from information_schema.SESSION_STATUS +where + variable_name like 'handler_read_rnd%' or + variable_name like 'Sort%'; -DROP TABLE t1, tmp; +# Check that Sort_priority_queue_sorts is used +select * from t2 where variable_name like 'Sort%'; + +# Check that we did scan the whole table and did LIMIT lookups +select * from t2 where variable_name='HANDLER_READ_RND'; + +select + if(variable_value in (87701, 87802), 'OK', 'FAIL') as RES +from t2 where variable_name='HANDLER_READ_RND_NEXT'; + + +DROP TABLE t1, tmp, t2; diff --git a/mysql-test/main/outfile_loaddata.result b/mysql-test/main/outfile_loaddata.result index 4356f8b113e..1449cb19453 100644 --- a/mysql-test/main/outfile_loaddata.result +++ b/mysql-test/main/outfile_loaddata.result @@ -124,19 +124,16 @@ ERROR 42000: Field separator argument is not what is expected; check the manual # LOAD DATA rises error or has unpredictable result -- to be fixed later SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS ENCLOSED BY 'ÑŠ'; Warnings: -Warning 1287 ' INTO FROM...' instead Warning 1638 Non-ASCII separator arguments are not fully supported LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET binary FIELDS ENCLOSED BY 'ÑŠ'; ERROR 42000: Field separator argument is not what is expected; check the manual SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS ESCAPED BY 'ÑŠ'; Warnings: -Warning 1287 ' INTO FROM...' instead Warning 1638 Non-ASCII separator arguments are not fully supported LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET binary FIELDS ESCAPED BY 'ÑŠ'; ERROR 42000: Field separator argument is not what is expected; check the manual SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FIELDS TERMINATED BY 'ÑŠ'; Warnings: -Warning 1287 ' INTO FROM...' instead Warning 1638 Non-ASCII separator arguments are not fully supported ################################################## 1ÑŠABC-áâ÷ÑŠDEF-ÂÃÄ @@ -160,7 +157,6 @@ a b c 2 NULL NULL SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES STARTING BY 'ÑŠ'; Warnings: -Warning 1287 ' INTO FROM...' instead Warning 1638 Non-ASCII separator arguments are not fully supported ################################################## ÑŠ1 ABC-áâ÷ DEF-ÂÃÄ @@ -176,7 +172,6 @@ a b c 2 NULL NULL SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES TERMINATED BY 'ÑŠ'; Warnings: -Warning 1287 ' INTO FROM...' instead Warning 1638 Non-ASCII separator arguments are not fully supported ################################################## 1 ABC-áâ÷ DEF-ÂÃÄÑŠ2 \N \NÑŠ################################################## diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result index 50be9dc49c8..c0c459e57b4 100644 --- a/mysql-test/main/parser.result +++ b/mysql-test/main/parser.result @@ -764,11 +764,8 @@ SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 FOR UPDATE; # "INTO" clause tests SELECT 1 FROM t1 INTO @var17727401; Warnings: -Warning 1287 ' INTO FROM...' instead Warning 1329 No data - zero rows fetched, selected, or processed SELECT 1 FROM DUAL INTO @var17727401; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT 1 INTO @var17727401; SELECT 1 INTO @var17727401 FROM t1; Warnings: @@ -784,7 +781,6 @@ Warnings: Warning 1329 No data - zero rows fetched, selected, or processed SELECT 1 FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1 INTO @var17727401; Warnings: -Warning 1287 ' INTO FROM...' instead Warning 1329 No data - zero rows fetched, selected, or processed SELECT 1 FROM t1 WHERE 1 INTO @var17727401 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1' at line 1 @@ -804,7 +800,6 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INTO @var17727401) UNION (SELECT 1 FROM t1 INTO t1)' at line 1 SELECT 1 FROM t1 UNION SELECT 1 FROM t1 INTO @var17727401; Warnings: -Warning 1287 ' INTO FROM...' instead Warning 1329 No data - zero rows fetched, selected, or processed SELECT 1 INTO @var17727401 FROM t1 PROCEDURE ANALYSE(); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'PROCEDURE ANALYSE()' at line 1 diff --git a/mysql-test/main/partition.result b/mysql-test/main/partition.result index 0d37d4cb168..ad4c3cf1ad3 100644 --- a/mysql-test/main/partition.result +++ b/mysql-test/main/partition.result @@ -2361,11 +2361,11 @@ b c EXPLAIN SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range bc bc 10 NULL 8 Using where; Using index for group-by +1 SIMPLE t1 ref bc bc 5 const 23 Using where; Using index EXPLAIN SELECT b, c FROM t1 WHERE b = 1 or b=2 GROUP BY b, c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range bc bc 10 NULL 8 Using where; Using index for group-by +1 SIMPLE t1 range bc bc 5 NULL 23 Using where; Using index DROP TABLE t1; # # Bug #45807: crash accessing partitioned table and sql_mode diff --git a/mysql-test/main/partition_explicit_prune.result b/mysql-test/main/partition_explicit_prune.result index 07af2d58a42..20a3d5bb8c0 100644 --- a/mysql-test/main/partition_explicit_prune.result +++ b/mysql-test/main/partition_explicit_prune.result @@ -470,7 +470,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE TableAlias p0-9_subp3 index NULL b 71 NULL 3 Using index EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 PARTITION (`p10-99`); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p10-99_subp4,p10-99_subp5 index NULL PRIMARY 4 NULL 2 Using index +1 SIMPLE t1 p10-99_subp4,p10-99_subp5 index NULL b 71 NULL 2 Using index EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1000000; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables @@ -693,8 +693,6 @@ a b -21 REPLACEd by REPLACE FLUSH STATUS; SELECT * FROM t1 PARTITION (pNeg, `p10-99`) INTO OUTFILE 'loadtest.txt'; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0; VARIABLE_NAME VARIABLE_VALUE @@ -1939,7 +1937,7 @@ MOD(seq, 100), seq_1_to_5000; explain select * from t1 partition (p1) where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where +1 SIMPLE t1 ref|filter a,b a|b 5|5 const 49 (1%) Using where; Using rowid filter flush tables; select * from t1 partition (p1)where a=10 and b=10; pk a b filler diff --git a/mysql-test/main/partition_mrr_aria.result b/mysql-test/main/partition_mrr_aria.result index 7ff5c9b63ed..c7983007281 100644 --- a/mysql-test/main/partition_mrr_aria.result +++ b/mysql-test/main/partition_mrr_aria.result @@ -130,7 +130,7 @@ set optimizer_switch='mrr=on'; explain extended select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = t2.a-1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 range idx idx 5 NULL 2 100.00 Using where; Using index -1 SIMPLE t0 ref idx idx 5 test.t2.a 12 100.00 Using index condition(BKA); Using join buffer (flat, BKA join); Rowid-ordered scan +1 SIMPLE t0 ALL idx NULL NULL NULL 50 25.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t0`.`tp` AS `tp`,`test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t0`.`c` AS `c`,`test`.`t2`.`a` AS `a` from `test`.`t0` join `test`.`t2` where `test`.`t0`.`a` = `test`.`t2`.`a` and `test`.`t2`.`a` in (3,4) and `test`.`t0`.`b` / 10 = `test`.`t2`.`a` - 1 select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = t2.a-1; @@ -164,7 +164,7 @@ tp a b c a explain extended select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = 4; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 range idx idx 5 NULL 2 100.00 Using where; Using index -1 SIMPLE t0 ref idx idx 5 test.t2.a 12 100.00 Using index condition; Using join buffer (flat, BKA join); Rowid-ordered scan +1 SIMPLE t0 ALL idx NULL NULL NULL 50 25.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t0`.`tp` AS `tp`,`test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t0`.`c` AS `c`,`test`.`t2`.`a` AS `a` from `test`.`t0` join `test`.`t2` where `test`.`t0`.`a` = `test`.`t2`.`a` and `test`.`t2`.`a` in (3,4) and `test`.`t0`.`b` / 10 = 4 select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = 4; diff --git a/mysql-test/main/partition_mrr_innodb.result b/mysql-test/main/partition_mrr_innodb.result index 98819021a6d..7d91fafef7c 100644 --- a/mysql-test/main/partition_mrr_innodb.result +++ b/mysql-test/main/partition_mrr_innodb.result @@ -130,7 +130,7 @@ set optimizer_switch='mrr=on'; explain extended select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = t2.a-1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 range idx idx 5 NULL 2 100.00 Using where; Using index -1 SIMPLE t0 ref idx idx 5 test.t2.a 12 100.00 Using index condition(BKA); Using join buffer (flat, BKA join); Rowid-ordered scan +1 SIMPLE t0 ALL idx NULL NULL NULL 50 25.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t0`.`tp` AS `tp`,`test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t0`.`c` AS `c`,`test`.`t2`.`a` AS `a` from `test`.`t0` join `test`.`t2` where `test`.`t0`.`a` = `test`.`t2`.`a` and `test`.`t2`.`a` in (3,4) and `test`.`t0`.`b` / 10 = `test`.`t2`.`a` - 1 select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = t2.a-1; @@ -164,7 +164,7 @@ tp a b c a explain extended select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = 4; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 range idx idx 5 NULL 2 100.00 Using where; Using index -1 SIMPLE t0 ref idx idx 5 test.t2.a 12 100.00 Using index condition; Using join buffer (flat, BKA join); Rowid-ordered scan +1 SIMPLE t0 ALL idx NULL NULL NULL 50 25.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t0`.`tp` AS `tp`,`test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t0`.`c` AS `c`,`test`.`t2`.`a` AS `a` from `test`.`t0` join `test`.`t2` where `test`.`t0`.`a` = `test`.`t2`.`a` and `test`.`t2`.`a` in (3,4) and `test`.`t0`.`b` / 10 = 4 select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = 4; diff --git a/mysql-test/main/partition_mrr_myisam.result b/mysql-test/main/partition_mrr_myisam.result index c3ce2935417..9155851a60a 100644 --- a/mysql-test/main/partition_mrr_myisam.result +++ b/mysql-test/main/partition_mrr_myisam.result @@ -130,7 +130,7 @@ set optimizer_switch='mrr=on'; explain extended select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = t2.a-1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 range idx idx 5 NULL 2 100.00 Using where; Using index -1 SIMPLE t0 ref idx idx 5 test.t2.a 12 100.00 Using index condition(BKA); Using join buffer (flat, BKA join); Rowid-ordered scan +1 SIMPLE t0 ALL idx NULL NULL NULL 50 25.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t0`.`tp` AS `tp`,`test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t0`.`c` AS `c`,`test`.`t2`.`a` AS `a` from `test`.`t0` join `test`.`t2` where `test`.`t0`.`a` = `test`.`t2`.`a` and `test`.`t2`.`a` in (3,4) and `test`.`t0`.`b` / 10 = `test`.`t2`.`a` - 1 select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = t2.a-1; @@ -164,7 +164,7 @@ tp a b c a explain extended select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = 4; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 range idx idx 5 NULL 2 100.00 Using where; Using index -1 SIMPLE t0 ref idx idx 5 test.t2.a 12 100.00 Using index condition; Using join buffer (flat, BKA join); Rowid-ordered scan +1 SIMPLE t0 ALL idx NULL NULL NULL 50 25.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t0`.`tp` AS `tp`,`test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t0`.`c` AS `c`,`test`.`t2`.`a` AS `a` from `test`.`t0` join `test`.`t2` where `test`.`t0`.`a` = `test`.`t2`.`a` and `test`.`t2`.`a` in (3,4) and `test`.`t0`.`b` / 10 = 4 select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = 4; @@ -288,7 +288,7 @@ explain select * from t0,t2 where t2.a in (3,4) and t0.a=t2.a and (t0.b / 10) = 4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range idx idx 5 NULL 2 Using where; Using index -1 SIMPLE t0 ref idx idx 5 test.t2.a 12 Using index condition; Using join buffer (flat, BKA join); Rowid-ordered scan +1 SIMPLE t0 ALL idx NULL NULL NULL 50 Using where; Using join buffer (flat, BNL join) # This will use "Using index condition(BKA)" explain select * from t1,t2 where t2.a in (3,4) and t1.a=t2.a and (t1.b / 10) = 4; diff --git a/mysql-test/main/partition_pruning.result b/mysql-test/main/partition_pruning.result index ec0cb144a51..6834cf0e657 100644 --- a/mysql-test/main/partition_pruning.result +++ b/mysql-test/main/partition_pruning.result @@ -15,13 +15,13 @@ PARTITION max VALUES LESS THAN MAXVALUE); INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8); EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; id select_type table partitions type possible_keys key key_len ref rows Extra -# # # # # # # # # 3 # +# # # # range # # # # 3 # EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; id select_type table partitions type possible_keys key key_len ref rows Extra -# # # # # # # # # 8 # +# # # # index # # # # 10 # EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; id select_type table partitions type possible_keys key key_len ref rows Extra -# # # # # # # # # 3 # +# # # # range # # # # 3 # DROP TABLE t1; # # Bug#49742: Partition Pruning not working correctly for RANGE @@ -92,7 +92,7 @@ a 5 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5 range PRIMARY PRIMARY 4 NULL 7 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 7 Using where; Using index SELECT * FROM t1 WHERE a < 7; a -1 @@ -105,7 +105,7 @@ a 6 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index SELECT * FROM t1 WHERE a <= 1; a -1 @@ -155,7 +155,7 @@ a 5 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5 range PRIMARY PRIMARY 4 NULL 7 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 7 Using where; Using index SELECT * FROM t1 WHERE a <= 6; a -1 @@ -168,7 +168,7 @@ a 6 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index SELECT * FROM t1 WHERE a <= 7; a -1 @@ -182,7 +182,7 @@ a 7 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 7; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index SELECT * FROM t1 WHERE a = 1; a 1 @@ -237,7 +237,7 @@ a 8 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +1 SIMPLE t1 p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 8 Using where; Using index SELECT * FROM t1 WHERE a >= 2; a 2 @@ -424,7 +424,7 @@ a 5 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 7 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index SELECT * FROM t1 WHERE a <= 1; a -1 @@ -474,7 +474,7 @@ a 5 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 7 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index SELECT * FROM t1 WHERE a <= 6; a -1 @@ -487,7 +487,7 @@ a 6 EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index SELECT * FROM t1 WHERE a = 1; a 1 @@ -2677,12 +2677,12 @@ select * from t1 X, t1 Y where X.b = Y.b and (X.a=1 or X.a=2) and (Y.a=2 or Y.a=3); id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE X p1,p2 range a,b a 4 NULL 4 Using where -1 SIMPLE Y p2,p3 ref a,b b 4 test.X.b 2 Using where +1 SIMPLE Y p2,p3 ref|filter a,b b|a 4|4 test.X.b 1 (50%) Using where; Using rowid filter explain partitions select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2); id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE X p1,p2 range a a 4 NULL 4 Using where -1 SIMPLE Y p1,p2 ref a a 4 test.X.a 2 +1 SIMPLE Y p1,p2 ref a a 4 test.X.a 1 drop table t1; create table t1 (a int) partition by hash(a) partitions 20; insert into t1 values (1),(2),(3); @@ -3465,8 +3465,8 @@ select * from t1 where company_id = 1000 and dept_id in (select dept_id from t2 where COMPANY_ID = 1000); id select_type table partitions type possible_keys key key_len ref rows Extra -1 PRIMARY t2 p_1000 ref PRIMARY PRIMARY 8 const 3 Using index -1 PRIMARY t1 p_1000 ALL PRIMARY NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t1 p_1000 ref PRIMARY PRIMARY 8 const 6 Using where +1 PRIMARY t2 p_1000 eq_ref PRIMARY PRIMARY 16 const,test.t1.dept_id 1 Using index drop table t1,t2; # # MDEV-9505: Valgrind failure in SEL_ARG::store_min,find_used_partitions,... diff --git a/mysql-test/main/partition_pruning.test b/mysql-test/main/partition_pruning.test index d59f52be313..78924d27550 100644 --- a/mysql-test/main/partition_pruning.test +++ b/mysql-test/main/partition_pruning.test @@ -25,11 +25,11 @@ PARTITION max VALUES LESS THAN MAXVALUE); INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8); ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 11 # +--replace_column 1 # 2 # 3 # 4 # 6 # 7 # 8 # 9 # 11 # EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 11 # +--replace_column 1 # 2 # 3 # 4 # 6 # 7 # 8 # 9 # 11 # EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; ---replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 11 # +--replace_column 1 # 2 # 3 # 4 # 6 # 7 # 8 # 9 # 11 # EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; DROP TABLE t1; diff --git a/mysql-test/main/partition_range.result b/mysql-test/main/partition_range.result index 9cefe83e1e2..be1689b218e 100644 --- a/mysql-test/main/partition_range.result +++ b/mysql-test/main/partition_range.result @@ -4,23 +4,26 @@ drop table if exists t1, t2; # CREATE TABLE t1 (a INT,b INT,KEY a (a,b)); INSERT INTO `t1` VALUES (0,580092),(3000,894076),(4000,805483),(4000,913540),(6000,611137),(8000,171602),(9000,599495),(9000,746305),(10000,272829),(10000,847519),(12000,258869),(12000,929028),(13000,288970),(15000,20971),(15000,105839),(16000,788272),(17000,76914),(18000,827274),(19000,802258),(20000,123677),(20000,587729),(22000,701449),(25000,31565),(25000,230782),(25000,442887),(25000,733139),(25000,851020); +SELECT COUNT(*) from t1 where a IN (10000, 1000000, 3000); +COUNT(*) +3 EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10000, 1000000, 3000) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index for group-by alter table t1 partition by hash(a) partitions 1; EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10000, 1000000, 3000) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index for group-by alter table t1 remove partitioning; insert into t1 (a,b) select seq,seq from seq_4001_to_4100; insert into t1 (a,b) select seq,seq from seq_10001_to_10100; EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10000, 1000000, 3000) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index for group-by alter table t1 partition by hash(a) partitions 1; EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10000, 1000000, 3000) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index for group-by DROP TABLE t1; create table t1 (a DATETIME) partition by range (TO_DAYS(a)) @@ -955,6 +958,11 @@ CREATE TABLE t1 ( a INT, b INT, KEY ( a, b ) +); +CREATE TABLE t1_part ( +a INT, +b INT, +KEY ( a, b ) ) PARTITION BY HASH (a) PARTITIONS 1; CREATE TABLE t2 ( a INT, @@ -966,36 +974,68 @@ INSERT INTO t1 SELECT a + 5, b + 5 FROM t1; INSERT INTO t1 SELECT a + 10, b + 10 FROM t1; INSERT INTO t1 SELECT a + 20, b + 20 FROM t1; INSERT INTO t1 SELECT a + 40, b + 40 FROM t1; +INSERT INTO t1 values(10,0),(10,1),(10,2),(100,0),(100,1); +select count(*) from t1; +count(*) +85 +select count(*) from t1 where a=10; +count(*) +4 +select count(*) from t1 where a=100; +count(*) +2 +INSERT INTO t1_part SELECT * FROM t1; INSERT INTO t2 SELECT * FROM t1; -ANALYZE TABLE t1,t2; +ANALYZE TABLE t1_part,t2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status OK +test.t1_part analyze status Engine-independent statistics collected +test.t1_part analyze status OK test.t2 analyze status Engine-independent statistics collected test.t2 analyze status Table is already up to date # plans should be identical -EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a; +EXPLAIN SELECT a, MAX(b) FROM t1_part WHERE a IN (10,100) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index +1 SIMPLE t1_part range a a 5 NULL 2 Using where; Using index for group-by EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index +1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by FLUSH status; -SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a; +SELECT a, MAX(b) FROM t1_part WHERE a IN (10, 100) GROUP BY a; a MAX(b) 10 10 -# Should be no more than 4 reads. -SHOW status LIKE 'handler_read_key'; +100 1 +SHOW status LIKE 'handler_read%'; Variable_name Value -Handler_read_key 2 +Handler_read_first 0 +Handler_read_key 6 +Handler_read_last 1 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 FLUSH status; SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a; a MAX(b) 10 10 -# Should be no more than 4 reads. -SHOW status LIKE 'handler_read_key'; +100 1 +SHOW status LIKE 'handler_read%'; Variable_name Value -Handler_read_key 2 +Handler_read_first 0 +Handler_read_key 6 +Handler_read_last 1 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +insert into t2 select 100,seq from seq_1_to_100; +EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by +DROP TABLE t1,t1_part,t2; # # MDEV-18501 Partition pruning doesn't work for historical queries # @@ -1023,7 +1063,7 @@ d select * from t1 partition (p1); d 2000-01-01 00:00:01.000000 -DROP TABLE t1, t2; +DROP TABLE t1; # # MDEV-21195 INSERT chooses wrong partition for RANGE partitioning by DECIMAL column # diff --git a/mysql-test/main/partition_range.test b/mysql-test/main/partition_range.test index f56851217cf..a7073122bbb 100644 --- a/mysql-test/main/partition_range.test +++ b/mysql-test/main/partition_range.test @@ -17,6 +17,7 @@ drop table if exists t1, t2; CREATE TABLE t1 (a INT,b INT,KEY a (a,b)); INSERT INTO `t1` VALUES (0,580092),(3000,894076),(4000,805483),(4000,913540),(6000,611137),(8000,171602),(9000,599495),(9000,746305),(10000,272829),(10000,847519),(12000,258869),(12000,929028),(13000,288970),(15000,20971),(15000,105839),(16000,788272),(17000,76914),(18000,827274),(19000,802258),(20000,123677),(20000,587729),(22000,701449),(25000,31565),(25000,230782),(25000,442887),(25000,733139),(25000,851020); +SELECT COUNT(*) from t1 where a IN (10000, 1000000, 3000); EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10000, 1000000, 3000) GROUP BY a; alter table t1 partition by hash(a) partitions 1; @@ -941,10 +942,17 @@ drop table t1, t2; --echo # Bug#50939: Loose Index Scan unduly relies on engine to remember range --echo # endpoints --echo # + CREATE TABLE t1 ( a INT, b INT, KEY ( a, b ) +); + +CREATE TABLE t1_part ( + a INT, + b INT, + KEY ( a, b ) ) PARTITION BY HASH (a) PARTITIONS 1; CREATE TABLE t2 ( @@ -959,24 +967,35 @@ INSERT INTO t1 SELECT a + 5, b + 5 FROM t1; INSERT INTO t1 SELECT a + 10, b + 10 FROM t1; INSERT INTO t1 SELECT a + 20, b + 20 FROM t1; INSERT INTO t1 SELECT a + 40, b + 40 FROM t1; +INSERT INTO t1 values(10,0),(10,1),(10,2),(100,0),(100,1); +select count(*) from t1; +select count(*) from t1 where a=10; +select count(*) from t1 where a=100; +INSERT INTO t1_part SELECT * FROM t1; INSERT INTO t2 SELECT * FROM t1; -ANALYZE TABLE t1,t2; +ANALYZE TABLE t1_part,t2; --echo # plans should be identical -EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a; +EXPLAIN SELECT a, MAX(b) FROM t1_part WHERE a IN (10,100) GROUP BY a; EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; +# view protocol will cause changed table counters +--disable_view_protocol FLUSH status; -SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a; ---echo # Should be no more than 4 reads. -SHOW status LIKE 'handler_read_key'; +SELECT a, MAX(b) FROM t1_part WHERE a IN (10, 100) GROUP BY a; +SHOW status LIKE 'handler_read%'; FLUSH status; SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a; ---echo # Should be no more than 4 reads. -SHOW status LIKE 'handler_read_key'; +SHOW status LIKE 'handler_read%'; + +--enable_view_protocol +insert into t2 select 100,seq from seq_1_to_100; +EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; + +DROP TABLE t1,t1_part,t2; --echo # --echo # MDEV-18501 Partition pruning doesn't work for historical queries @@ -1005,7 +1024,7 @@ insert into t1 values select * from t1 partition (p0); select * from t1 partition (p1); -DROP TABLE t1, t2; +DROP TABLE t1; --echo # --echo # MDEV-21195 INSERT chooses wrong partition for RANGE partitioning by DECIMAL column diff --git a/mysql-test/main/percona_nonflushing_analyze_debug.result b/mysql-test/main/percona_nonflushing_analyze_debug.result index 78da085f26f..c3388fa42ed 100644 --- a/mysql-test/main/percona_nonflushing_analyze_debug.result +++ b/mysql-test/main/percona_nonflushing_analyze_debug.result @@ -1,7 +1,7 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 VALUES (1), (2), (3); connect con1,localhost,root; -SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; +SET DEBUG_SYNC="handler_rnd_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; SELECT * FROM t1; connection default; SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress"; diff --git a/mysql-test/main/pool_of_threads.result b/mysql-test/main/pool_of_threads.result index 91ad7ab098f..718cb7dc8ce 100644 --- a/mysql-test/main/pool_of_threads.result +++ b/mysql-test/main/pool_of_threads.result @@ -1,5 +1,6 @@ SET optimizer_switch='outer_join_with_cache=off'; drop table if exists t1,t2,t3,t4; +set @@default_storage_engine="aria"; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -600,6 +601,9 @@ explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +# +# Some test with ORDER BY and limit +# explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort @@ -1289,7 +1293,7 @@ companynr tinyint(2) unsigned zerofill NOT NULL default '00', companyname char(30) NOT NULL default '', PRIMARY KEY (companynr), UNIQUE KEY companyname(companyname) -) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +) ENGINE=aria MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; companynr companyname 00 Unknown @@ -1379,6 +1383,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t2 where fld1=999999; +# +# Test left join optimization +# explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where @@ -1393,15 +1400,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; id select_type table type possible_keys key key_len ref rows Extra @@ -1417,11 +1424,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index d5e501b06ef..d60fa28fc96 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -244,8 +244,6 @@ prepare stmt1 from "insert into t1 select i from t1"; execute stmt1; execute stmt1; prepare stmt1 from "select * from t1 into outfile '/tmp/f1.txt'"; -Warnings: -Warning 1287 ' INTO FROM...' instead execute stmt1; deallocate prepare stmt1; drop table t1; @@ -5554,13 +5552,11 @@ CREATE TABLE t2 (c2 INT) ENGINE=MyISAM; CREATE TABLE t3 (c3 INT) ENGINE=MyISAM; EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 ); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE PREPARE stmt FROM "EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 )"; EXECUTE stmt; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DEALLOCATE PREPARE stmt; DROP TABLE t1, t2, t3; # diff --git a/mysql-test/main/ps_1general.result b/mysql-test/main/ps_1general.result index ca2447b6b26..b71057248b6 100644 --- a/mysql-test/main/ps_1general.result +++ b/mysql-test/main/ps_1general.result @@ -451,7 +451,7 @@ def Extra 253 255 14 N 1 39 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort SET @arg00=1 ; -prepare stmt1 from ' explain select a from t1 where a > ? order by b '; +prepare stmt1 from ' explain select a from t1 force index (primary) where a > ? order by b '; execute stmt1 using @arg00; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 Y 32928 0 63 diff --git a/mysql-test/main/ps_1general.test b/mysql-test/main/ps_1general.test index 20f2ad019f4..c98fc4a5619 100644 --- a/mysql-test/main/ps_1general.test +++ b/mysql-test/main/ps_1general.test @@ -437,8 +437,10 @@ prepare stmt3 from ' unlock tables ' ; ## Load/Unload table contents --let $datafile = $MYSQLTEST_VARDIR/tmp/data.txt +--disable_warnings --error 0,1 --remove_file $datafile +--enable_warnings --replace_result $MYSQLTEST_VARDIR eval prepare stmt1 from ' load data infile ''$datafile'' @@ -497,7 +499,7 @@ prepare stmt1 from ' explain select a from t1 order by b '; execute stmt1; --disable_metadata SET @arg00=1 ; -prepare stmt1 from ' explain select a from t1 where a > ? order by b '; +prepare stmt1 from ' explain select a from t1 force index (primary) where a > ? order by b '; --enable_metadata --replace_result 4096 4_OR_8_K 8192 4_OR_8_K execute stmt1 using @arg00; diff --git a/mysql-test/main/ps_ddl.result b/mysql-test/main/ps_ddl.result index dcbb6982702..00243b93acc 100644 --- a/mysql-test/main/ps_ddl.result +++ b/mysql-test/main/ps_ddl.result @@ -20,8 +20,6 @@ else select '' as "SUCCESS"; end if; end| -Warnings: -Warning 1287 ' INTO FROM...' instead set @reprepare_count= 0; flush status; ===================================================================== @@ -1075,8 +1073,6 @@ call p1(x); return x; end| create procedure p1(out x int) select max(a) from t1 into x; -Warnings: -Warning 1287 ' INTO FROM...' instead prepare stmt from "select * from v1"; execute stmt; f1() @@ -1089,8 +1085,6 @@ SUCCESS drop procedure p1; create procedure p1(out x int) select max(a) from t2 into x; -Warnings: -Warning 1287 ' INTO FROM...' instead # XXX: used to be a bug. The prelocked list was not invalidated # and we kept opening table t1, whereas the procedure # is now referring to table t2 diff --git a/mysql-test/main/ps_ddl1.result b/mysql-test/main/ps_ddl1.result index 5178ee64f16..667cbed8a7a 100644 --- a/mysql-test/main/ps_ddl1.result +++ b/mysql-test/main/ps_ddl1.result @@ -20,8 +20,6 @@ else select '' as "SUCCESS"; end if; end| -Warnings: -Warning 1287 ' INTO FROM...' instead set @reprepare_count= 0; flush status; drop table if exists t1; diff --git a/mysql-test/main/query_cache.result b/mysql-test/main/query_cache.result index f78a6ccc388..e73f219e1b0 100644 --- a/mysql-test/main/query_cache.result +++ b/mysql-test/main/query_cache.result @@ -646,13 +646,9 @@ show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 select * from t1 into outfile "query_cache.out.file"; -Warnings: -Warning 1287 ' INTO FROM...' instead select * from t1 into outfile "query_cache.out.file"; ERROR HY000: File 'query_cache.out.file' already exists select * from t1 limit 1 into dumpfile "query_cache.dump.file"; -Warnings: -Warning 1287 ' INTO FROM...' instead show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 @@ -1105,8 +1101,6 @@ Declare var1 int; select max(a) from t1 into var1; return var1; end// -Warnings: -Warning 1287 ' INTO FROM...' instead create procedure `p1`() begin select a, f1() from t1; diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index 6ff4f409666..6d9f2d8b1c3 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -309,6 +309,9 @@ a b 15 1 47 1 DROP TABLE t1; +# +# Test of problem with IN on many different keyparts. (Bug #4157) +# CREATE TABLE t1 ( id int( 11 ) unsigned NOT NULL AUTO_INCREMENT , line int( 5 ) unsigned NOT NULL default '0', @@ -325,10 +328,17 @@ KEY `LINES` ( owner, tableid, content, id ) , KEY recount( owner, line ) ) ENGINE = MYISAM; INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5); +INSERT into t1 (owner,id,columnid,line) select 11,seq+20,seq,seq from seq_1_to_100; +explain SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY,menu,COLUMN,LINES,recount COLUMN 4 const 11 Using index condition SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30; id columnid tableid content showid line ordinal -15 15 1 188 1 1 0 13 13 1 188 1 5 0 +15 15 1 188 1 1 0 +33 13 1 188 1 13 0 +34 14 1 188 1 14 0 +35 15 1 188 1 15 0 drop table t1; create table t1 (id int(10) primary key); insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -723,7 +733,7 @@ WHERE v.oxrootid ='d8c4177d09f8b11f5.52725521' AND s.oxleft > v.oxleft AND s.oxleft < v.oxright; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE v ALL OXLEFT,OXRIGHT,OXROOTID NULL NULL NULL 12 Using where +1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 6 Using index condition 1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4) SELECT s.oxid FROM t1 v, t1 s WHERE @@ -1236,14 +1246,16 @@ insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t2 (a int, b int, filler char(100)); insert into t2 select A.a + 10 * (B.a + 10 * C.a), 10, 'filler' from t1 A, t1 B, t1 C where A.a < 5; -insert into t2 select 1000, b, 'filler' from t2; +insert into t2 select 1000, b, 'filler' from t2 limit 50; +select count(*) from t2; +count(*) +550 alter table t2 add index (a,b); -select 'In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)' Z; -Z -In following EXPLAIN the access method should be ref, #rows~=500 (and not 2) +# In following EXPLAIN the access method should be ref, #rows~=50 +# (and not 2) when we are not using rowid-ordered scans explain select * from t2 where a=1000 and b<11; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref a a 5 const 503 Using index condition +1 SIMPLE t2 range a a 10 NULL 63 Using index condition drop table t1, t2; CREATE TABLE t1( a INT, b INT, KEY( a, b ) ); CREATE TABLE t2( a INT, b INT, KEY( a, b ) ); @@ -2412,6 +2424,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2421,7 +2434,9 @@ EXPLAIN "key": "idx", "key_length": "10", "used_key_parts": ["a", "b"], + "loops": 1, "rows": 6, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t1.b) in (((2,3)),((3,3)),((8,8)),((7,7)))" } @@ -2476,6 +2491,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2485,7 +2501,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t1.b + t1.a) in (((4,9)),((8,8)),((7,7)))" } @@ -2506,6 +2524,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2515,7 +2534,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t1.b) in ((4,t1.a - 1),(8,t1.a + 8),(7,t1.a + 7))" } @@ -2550,6 +2571,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2567,7 +2589,9 @@ EXPLAIN "rows": 12, "selectivity_pct": 60 }, + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 60, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((3,3)),((7,7)),((2,2)))" @@ -2582,7 +2606,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.d"], + "loops": 1.8, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2636,6 +2662,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2653,7 +2680,9 @@ EXPLAIN "rows": 15, "selectivity_pct": 14.42307692 }, + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 14.42307663, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((3,3)),((7,7)),((8,8))) and octet_length(t2.f) = 1" @@ -2668,8 +2697,10 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.d"], + "loops": 1.153846154, "rows": 8, - "filtered": 100 + "cost": "COST_REPLACED", + "filtered": 73.17073059 } } ] @@ -2678,60 +2709,60 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1; a b c d e f -3 2 uuuw 3 3 i 3 2 uuua 3 3 i -3 3 zzzz 3 3 i +3 2 uuua 3 3 i +3 2 uuuw 3 3 i +3 2 uuuw 3 3 i +3 3 zyxa 3 3 i +3 3 zyxa 3 3 i +3 3 zyxw 3 3 i 3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -3 2 uuuw 3 3 i -3 2 uuua 3 3 i -3 3 zzzz 3 3 i -3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -7 7 xxxyy 7 7 h +3 3 zzzz 3 3 i +3 3 zzzz 3 3 i 7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h +7 8 xxxxx 7 7 h prepare stmt from "select * from t1,t2 where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1"; execute stmt; a b c d e f -3 2 uuuw 3 3 i 3 2 uuua 3 3 i -3 3 zzzz 3 3 i +3 2 uuua 3 3 i +3 2 uuuw 3 3 i +3 2 uuuw 3 3 i +3 3 zyxa 3 3 i +3 3 zyxa 3 3 i +3 3 zyxw 3 3 i 3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -3 2 uuuw 3 3 i -3 2 uuua 3 3 i -3 3 zzzz 3 3 i -3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -7 7 xxxyy 7 7 h +3 3 zzzz 3 3 i +3 3 zzzz 3 3 i 7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h +7 8 xxxxx 7 7 h execute stmt; a b c d e f -3 2 uuuw 3 3 i 3 2 uuua 3 3 i -3 3 zzzz 3 3 i +3 2 uuua 3 3 i +3 2 uuuw 3 3 i +3 2 uuuw 3 3 i +3 3 zyxa 3 3 i +3 3 zyxa 3 3 i +3 3 zyxw 3 3 i 3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -3 2 uuuw 3 3 i -3 2 uuua 3 3 i -3 3 zzzz 3 3 i -3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -7 7 xxxyy 7 7 h +3 3 zzzz 3 3 i +3 3 zzzz 3 3 i 7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h +7 8 xxxxx 7 7 h deallocate prepare stmt; insert into t1 select * from t1; # join order: (t2,t1) with ref access of t1 @@ -2747,6 +2778,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2764,7 +2796,9 @@ EXPLAIN "rows": 7, "selectivity_pct": 6.730769231 }, + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 6.730769157, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and octet_length(t2.f) = 1" @@ -2779,7 +2813,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.d"], + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2789,14 +2825,14 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; a b c d e f -7 7 xxxyy 7 7 h +7 7 xxxya 7 7 h 7 7 xxxya 7 7 h 7 7 xxxyy 7 7 h -7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h +7 8 xxxxa 7 7 h 7 8 xxxxa 7 7 h 7 8 xxxxx 7 7 h -7 8 xxxxa 7 7 h +7 8 xxxxx 7 7 h alter table t2 drop index idx1, drop index idx2, add index idx3(d,e); # join order: (t2,t1) with ref access of t1 # range access to t2 by 2-component keys for index idx3 @@ -2811,6 +2847,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2820,7 +2857,9 @@ EXPLAIN "key": "idx3", "key_length": "10", "used_key_parts": ["d", "e"], + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and octet_length(t2.f) = 1" @@ -2835,7 +2874,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.d"], + "loops": 5, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2866,6 +2907,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2875,7 +2917,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 15, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a is not null" } @@ -2889,7 +2933,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "loops": 15, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t2.e) in ((4,t1.a + 1),(7,t1.a + 1),(8,t1.a + 1)) and octet_length(t2.f) = 1" } @@ -2900,22 +2946,22 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1; a b c d e f -4 3 zyx 4 5 a +4 3 zya 4 5 a 4 3 zya 4 5 a 4 3 zyx 4 5 a -4 3 zya 4 5 a -4 5 ww 4 5 a +4 3 zyx 4 5 a +4 5 wa 4 5 a 4 5 wa 4 5 a 4 5 ww 4 5 a -4 5 wa 4 5 a -7 7 xxxyy 7 8 b +4 5 ww 4 5 a +7 7 xxxya 7 8 b 7 7 xxxya 7 8 b 7 7 xxxyy 7 8 b -7 7 xxxya 7 8 b -7 8 xxxxx 7 8 b +7 7 xxxyy 7 8 b +7 8 xxxxa 7 8 b 7 8 xxxxa 7 8 b 7 8 xxxxx 7 8 b -7 8 xxxxa 7 8 b +7 8 xxxxx 7 8 b # join order: (t1,t2) with ref access of t2 # no range access explain select * from t1,t2 @@ -2929,13 +2975,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 144, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a is not null" } @@ -2949,7 +2998,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "loops": 144, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),((7,7)),((8,8))) and octet_length(t2.f) = 1" } @@ -2960,14 +3011,14 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1; a b c d e f -7 8 xxxxx 7 7 h +7 7 xxxya 7 7 h +7 7 xxxya 7 7 h +7 7 xxxyy 7 7 h 7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h -7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h -7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h -7 7 xxxya 7 7 h +7 8 xxxxx 7 7 h +7 8 xxxxx 7 7 h # join order: (t1,t2) with ref access of t2 # range access to t1 by 1-component keys for index idx explain select * from t1,t2 @@ -2983,6 +3034,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2992,7 +3044,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a is not null", "attached_condition": "(t1.a,2) in (((2,2)),((7,7)),((8,8))) and octet_length(t1.c) = 1" @@ -3007,7 +3061,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "loops": 12, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "octet_length(t2.f) = 1" } @@ -3066,6 +3122,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -3088,7 +3145,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a is not null", "attached_condition": "(t1.a,1 + 1) in (((2,2)),((7,7)),((8,8))) and octet_length(t1.c) = 1" @@ -3103,7 +3162,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "loops": 12, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "octet_length(t2.f) = 1" } @@ -3381,7 +3442,7 @@ insert into t2 select A.a + B.a*10 + C.a*100 from ten A, ten B,ten C where A.a + # expected type=range, rows=1487 , reason=using index dives analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 range a a 5 NULL 1487 1199.00 100.00 100.00 Using where; Using index +1 SIMPLE t1 index a a 5 NULL 2000 2000.00 74.35 59.95 Using where; Using index insert into t2 values (200),(201); # expected type=range, rows=201 , reason=using index statistics analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,200,201); diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test index c42670c1ed1..c2cc794b485 100644 --- a/mysql-test/main/range.test +++ b/mysql-test/main/range.test @@ -3,6 +3,8 @@ # Problem with range optimizer # --source include/have_innodb.inc +--source include/have_sequence.inc + SET optimizer_use_condition_selectivity=4; set @innodb_stats_persistent_save= @@innodb_stats_persistent; @@ -263,9 +265,9 @@ WHERE ); DROP TABLE t1; -# -# Test of problem with IN on many different keyparts. (Bug #4157) -# +--echo # +--echo # Test of problem with IN on many different keyparts. (Bug #4157) +--echo # CREATE TABLE t1 ( id int( 11 ) unsigned NOT NULL AUTO_INCREMENT , @@ -284,7 +286,10 @@ KEY recount( owner, line ) ) ENGINE = MYISAM; INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5); +INSERT into t1 (owner,id,columnid,line) select 11,seq+20,seq,seq from seq_1_to_100; +explain SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30; +--sorted_result SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30; drop table t1; @@ -1025,7 +1030,8 @@ create table t2 (a int, b int, filler char(100)); insert into t2 select A.a + 10 * (B.a + 10 * C.a), 10, 'filler' from t1 A, t1 B, t1 C where A.a < 5; -insert into t2 select 1000, b, 'filler' from t2; +insert into t2 select 1000, b, 'filler' from t2 limit 50; +select count(*) from t2; alter table t2 add index (a,b); # t2 values # ( 1 , 10, 'filler') @@ -1033,13 +1039,14 @@ alter table t2 add index (a,b); # ( 3 , 10, 'filler') # (... , 10, 'filler') # ... -# (1000, 10, 'filler') - 500 times +# (1000, 10, 'filler') - 100 times -# 500 rows, 1 row +# 50 rows, 1 row + +--echo # In following EXPLAIN the access method should be ref, #rows~=50 +--echo # (and not 2) when we are not using rowid-ordered scans -select 'In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)' Z; explain select * from t2 where a=1000 and b<11; - drop table t1, t2; # @@ -1913,6 +1920,7 @@ insert into t1 values let $q1= select * from t1 where (a,b) IN ((2, 3),(3,3),(8,8),(7,7)); eval explain $q1; +--source include/explain-no-costs.inc eval explain format=json $q1; eval $q1; eval prepare stmt from "$q1"; @@ -1924,6 +1932,7 @@ deallocate prepare stmt; let $q2= select * from t1 where (a,b+a) IN ((4,9),(8,8),(7,7)); eval explain $q2; +--source include/explain-no-costs.inc eval explain format=json $q2; eval $q2; @@ -1931,6 +1940,7 @@ eval $q2; let $q3= select * from t1 where (a,b) IN ((4,a-1),(8,a+8),(7,a+7)); eval explain $q3; +--source include/explain-no-costs.inc eval explain format=json $q3; eval $q3; @@ -1954,6 +1964,7 @@ let $q4= select * from t1,t2 where a = d and (a,e) in ((3,3),(7,7),(2,2)); eval explain $q4; +--source include/explain-no-costs.inc eval explain format=json $q4; eval $q4; @@ -1979,10 +1990,14 @@ let $q5= select * from t1,t2 where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1; eval explain $q5; +--source include/explain-no-costs.inc eval explain format=json $q5; +--sorted_result eval $q5; eval prepare stmt from "$q5"; +--sorted_result execute stmt; +--sorted_result execute stmt; deallocate prepare stmt; @@ -1994,7 +2009,9 @@ let $q6= select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; eval explain $q6; +--source include/explain-no-costs.inc eval explain format=json $q6; +--sorted_result eval $q6; alter table t2 drop index idx1, drop index idx2, add index idx3(d,e); @@ -2005,6 +2022,7 @@ let $q7= select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; eval explain $q7; +--source include/explain-no-costs.inc eval explain format=json $q7; eval $q7; @@ -2014,7 +2032,9 @@ let $q8= select * from t1,t2 where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1; eval explain $q8; +--source include/explain-no-costs.inc eval explain format=json $q8; +--sorted_result eval $q8; --echo # join order: (t1,t2) with ref access of t2 @@ -2023,7 +2043,9 @@ let $q9= select * from t1,t2 where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1; eval explain $q9; +--source include/explain-no-costs.inc eval explain format=json $q9; +--sorted_result eval $q9; --echo # join order: (t1,t2) with ref access of t2 @@ -2033,6 +2055,7 @@ select * from t1,t2 where a = d and (a,2) in ((2,2),(7,7),(8,8)) and length(c) = 1 and length(f) = 1; eval explain $q10; +--source include/explain-no-costs.inc eval explain format=json $q10; eval $q10; eval prepare stmt from "$q10"; @@ -2053,6 +2076,7 @@ select * from t1,t2,t3 (a,v+1) in ((2,2),(7,7),(8,8)) and length(c) = 1 and length(f) = 1; eval explain $q11; +--source include/explain-no-costs.inc eval explain format=json $q11; eval $q11; diff --git a/mysql-test/main/range_aria_dbt3.result b/mysql-test/main/range_aria_dbt3.result index f08a1b244f8..be3bc79c3a8 100644 --- a/mysql-test/main/range_aria_dbt3.result +++ b/mysql-test/main/range_aria_dbt3.result @@ -19,6 +19,16 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT COUNT(*) FROM lineitem WHERE l_orderkey BETWEEN 111 AND 262 OR ( l_orderkey BETWEEN 152 AND 672 AND l_linenumber BETWEEN 4 AND 9 ); COUNT(*) 293 +# +# MDEV-30486 Table is not eliminated in bb-11.0 +# +explain SELECT c_custkey, c_name AS currency2 FROM partsupp LEFT JOIN part ON ( p_partkey = ps_partkey ) JOIN supplier ON (s_suppkey = ps_suppkey) JOIN lineitem ON ( ps_suppkey = l_suppkey ) JOIN orders ON ( l_orderkey = o_orderkey ) JOIN customer ON ( o_custkey = c_custkey ) HAVING c_custkey > 150; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE supplier index PRIMARY PRIMARY 4 NULL 10 Using index +1 SIMPLE partsupp ref i_ps_suppkey i_ps_suppkey 4 dbt3_s001.supplier.s_suppkey 16 +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey 5 dbt3_s001.supplier.s_suppkey 100 +1 SIMPLE orders eq_ref PRIMARY,i_o_custkey PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +1 SIMPLE customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 DROP DATABASE dbt3_s001; # # End of 10.5 tests diff --git a/mysql-test/main/range_aria_dbt3.test b/mysql-test/main/range_aria_dbt3.test index 141bf43885b..b373d5b999b 100644 --- a/mysql-test/main/range_aria_dbt3.test +++ b/mysql-test/main/range_aria_dbt3.test @@ -26,6 +26,12 @@ explain SELECT COUNT(*) FROM lineitem WHERE l_orderkey BETWEEN 111 AND 262 OR ( SELECT COUNT(*) FROM lineitem WHERE l_orderkey BETWEEN 111 AND 262 OR ( l_orderkey BETWEEN 152 AND 672 AND l_linenumber BETWEEN 4 AND 9 ); +--echo # +--echo # MDEV-30486 Table is not eliminated in bb-11.0 +--echo # + +explain SELECT c_custkey, c_name AS currency2 FROM partsupp LEFT JOIN part ON ( p_partkey = ps_partkey ) JOIN supplier ON (s_suppkey = ps_suppkey) JOIN lineitem ON ( ps_suppkey = l_suppkey ) JOIN orders ON ( l_orderkey = o_orderkey ) JOIN customer ON ( o_custkey = c_custkey ) HAVING c_custkey > 150; + DROP DATABASE dbt3_s001; --echo # diff --git a/mysql-test/main/range_innodb.result b/mysql-test/main/range_innodb.result index eddfbfd0d62..826c0e4d90a 100644 --- a/mysql-test/main/range_innodb.result +++ b/mysql-test/main/range_innodb.result @@ -53,9 +53,9 @@ set optimizer_switch='extended_keys=on'; explain select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 2 -1 SIMPLE t1 ref PRIMARY,idx1,idx2 idx1 5 const 3 Using index condition -1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ref PRIMARY,idx1,idx2 idx1 5 const # +1 SIMPLE t2 ALL NULL NULL NULL NULL # Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL # Using where; Using join buffer (incremental, BNL join) select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0'; pk a b 1 6 0 @@ -83,6 +83,7 @@ drop table t1,t2; # MDEV-14440: Server crash in in handler::ha_external_lock or Assertion `inited==RND' # failed in handler::ha_rnd_end upon SELECT from partitioned table # +call mtr.add_suppression("Got error .* when reading table"); set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; create table t0(a int); @@ -97,7 +98,7 @@ SET @saved_dbug = @@GLOBAL.debug_dbug; set @@global.debug_dbug="+d,ha_index_init_fail"; explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where +1 SIMPLE t1 ref|filter a,b a|b 5|5 const 50 (2%) Using where; Using rowid filter select * from t1 where a=10 and b=10; ERROR HY000: Table definition has changed, please retry transaction DROP TABLE t0,t1; diff --git a/mysql-test/main/range_innodb.test b/mysql-test/main/range_innodb.test index 276b9cea08f..35511279910 100644 --- a/mysql-test/main/range_innodb.test +++ b/mysql-test/main/range_innodb.test @@ -58,6 +58,8 @@ insert into t3 values (3),(-1),(4); set @save_optimizer_switch=@@optimizer_switch; set optimizer_switch='extended_keys=on'; +# InnoDB sometimes returns 4 other times 5 records for t1 +--replace_column 9 # explain select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0'; select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0'; @@ -89,6 +91,8 @@ drop table t1,t2; --echo # failed in handler::ha_rnd_end upon SELECT from partitioned table --echo # +call mtr.add_suppression("Got error .* when reading table"); + set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; create table t0(a int); diff --git a/mysql-test/main/range_interrupted-13751.result b/mysql-test/main/range_interrupted-13751.result index 68610cdda8e..eadd32bffa0 100644 --- a/mysql-test/main/range_interrupted-13751.result +++ b/mysql-test/main/range_interrupted-13751.result @@ -1,11 +1,11 @@ CREATE TABLE t1 (i INT AUTO_INCREMENT, c VARCHAR(1), KEY(i), KEY(c,i)) ENGINE=MyISAM; -INSERT INTO t1 (c) VALUES ('a'),('b'),('c'),('d'); -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; +INSERT INTO t1 (c) select mid("abcdefgh", mod(seq,8)+1, 1) from seq_1_to_256; +explain SELECT 1 FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 +WHERE alias1.c = alias2.c OR alias1.i <= 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE alias2 index c c 8 NULL 256 Using index +1 SIMPLE alias3 index NULL i 4 NULL 256 Using index; Using join buffer (flat, BNL join) +1 SIMPLE alias1 ALL i,c NULL NULL NULL 256 Range checked for each record (index map: 0x3) set @old_dbug=@@session.debug_dbug; SET debug_dbug="+d,kill_join_init_read_record"; SELECT 1 FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 diff --git a/mysql-test/main/range_interrupted-13751.test b/mysql-test/main/range_interrupted-13751.test index b0793edeb9d..939f15b2145 100644 --- a/mysql-test/main/range_interrupted-13751.test +++ b/mysql-test/main/range_interrupted-13751.test @@ -1,17 +1,15 @@ --- source include/have_debug.inc +--source include/have_debug.inc --source include/default_optimizer_switch.inc +--source include/have_sequence.inc # # MDEV-13751 Interrupted SELECT fails with 1030: 'Got error 1 "Operation not permitted" from storage engine MyISAM' # CREATE TABLE t1 (i INT AUTO_INCREMENT, c VARCHAR(1), KEY(i), KEY(c,i)) ENGINE=MyISAM; -INSERT INTO t1 (c) VALUES ('a'),('b'),('c'),('d'); -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; -INSERT INTO t1 (c) SELECT c FROM t1; +INSERT INTO t1 (c) select mid("abcdefgh", mod(seq,8)+1, 1) from seq_1_to_256; + +explain SELECT 1 FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 +WHERE alias1.c = alias2.c OR alias1.i <= 1; set @old_dbug=@@session.debug_dbug; SET debug_dbug="+d,kill_join_init_read_record"; diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index c2c715a0a89..ba81a6c4cba 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -312,6 +312,9 @@ a b 15 1 47 1 DROP TABLE t1; +# +# Test of problem with IN on many different keyparts. (Bug #4157) +# CREATE TABLE t1 ( id int( 11 ) unsigned NOT NULL AUTO_INCREMENT , line int( 5 ) unsigned NOT NULL default '0', @@ -328,10 +331,17 @@ KEY `LINES` ( owner, tableid, content, id ) , KEY recount( owner, line ) ) ENGINE = MYISAM; INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5); +INSERT into t1 (owner,id,columnid,line) select 11,seq+20,seq,seq from seq_1_to_100; +explain SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY,menu,COLUMN,LINES,recount COLUMN 4 const 11 Using index condition SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30; id columnid tableid content showid line ordinal -15 15 1 188 1 1 0 13 13 1 188 1 5 0 +15 15 1 188 1 1 0 +33 13 1 188 1 13 0 +34 14 1 188 1 14 0 +35 15 1 188 1 15 0 drop table t1; create table t1 (id int(10) primary key); insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -726,7 +736,7 @@ WHERE v.oxrootid ='d8c4177d09f8b11f5.52725521' AND s.oxleft > v.oxleft AND s.oxleft < v.oxright; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE v ALL OXLEFT,OXRIGHT,OXROOTID NULL NULL NULL 12 Using where +1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 6 Using index condition 1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4) SELECT s.oxid FROM t1 v, t1 s WHERE @@ -1239,14 +1249,16 @@ insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t2 (a int, b int, filler char(100)); insert into t2 select A.a + 10 * (B.a + 10 * C.a), 10, 'filler' from t1 A, t1 B, t1 C where A.a < 5; -insert into t2 select 1000, b, 'filler' from t2; +insert into t2 select 1000, b, 'filler' from t2 limit 50; +select count(*) from t2; +count(*) +550 alter table t2 add index (a,b); -select 'In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)' Z; -Z -In following EXPLAIN the access method should be ref, #rows~=500 (and not 2) +# In following EXPLAIN the access method should be ref, #rows~=50 +# (and not 2) when we are not using rowid-ordered scans explain select * from t2 where a=1000 and b<11; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref a a 5 const 503 Using index condition +1 SIMPLE t2 range a a 10 NULL 63 Using index condition; Rowid-ordered scan drop table t1, t2; CREATE TABLE t1( a INT, b INT, KEY( a, b ) ); CREATE TABLE t2( a INT, b INT, KEY( a, b ) ); @@ -2415,6 +2427,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2424,7 +2437,9 @@ EXPLAIN "key": "idx", "key_length": "10", "used_key_parts": ["a", "b"], + "loops": 1, "rows": 6, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t1.b) in (((2,3)),((3,3)),((8,8)),((7,7)))", "mrr_type": "Rowid-ordered scan" @@ -2480,6 +2495,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2489,7 +2505,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t1.b + t1.a) in (((4,9)),((8,8)),((7,7)))", "mrr_type": "Rowid-ordered scan" @@ -2511,6 +2529,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2520,7 +2539,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t1.b) in ((4,t1.a - 1),(8,t1.a + 8),(7,t1.a + 7))", "mrr_type": "Rowid-ordered scan" @@ -2556,6 +2577,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2565,7 +2587,9 @@ EXPLAIN "key": "idx1", "key_length": "5", "used_key_parts": ["d"], + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 60, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((3,3)),((7,7)),((2,2)))", @@ -2581,7 +2605,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.d"], + "loops": 1.8, "rows": 8, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2635,6 +2661,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2644,7 +2671,9 @@ EXPLAIN "key": "idx1", "key_length": "5", "used_key_parts": ["d"], + "loops": 1, "rows": 8, + "cost": "COST_REPLACED", "filtered": 14.42307663, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((3,3)),((7,7)),((8,8))) and octet_length(t2.f) = 1", @@ -2660,8 +2689,10 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.d"], + "loops": 1.153846154, "rows": 8, - "filtered": 100 + "cost": "COST_REPLACED", + "filtered": 73.17073059 } } ] @@ -2670,60 +2701,60 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1; a b c d e f -3 2 uuuw 3 3 i 3 2 uuua 3 3 i -3 3 zzzz 3 3 i +3 2 uuua 3 3 i +3 2 uuuw 3 3 i +3 2 uuuw 3 3 i +3 3 zyxa 3 3 i +3 3 zyxa 3 3 i +3 3 zyxw 3 3 i 3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -7 7 xxxyy 7 7 h +3 3 zzza 3 3 i +3 3 zzzz 3 3 i +3 3 zzzz 3 3 i 7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h -3 2 uuuw 3 3 i -3 2 uuua 3 3 i -3 3 zzzz 3 3 i -3 3 zyxw 3 3 i -3 3 zzza 3 3 i -3 3 zyxa 3 3 i +7 8 xxxxx 7 7 h prepare stmt from "select * from t1,t2 where a = d and (a,e) in ((3,3),(7,7),(8,8)) and length(f) = 1"; execute stmt; a b c d e f -3 2 uuuw 3 3 i 3 2 uuua 3 3 i -3 3 zzzz 3 3 i +3 2 uuua 3 3 i +3 2 uuuw 3 3 i +3 2 uuuw 3 3 i +3 3 zyxa 3 3 i +3 3 zyxa 3 3 i +3 3 zyxw 3 3 i 3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -7 7 xxxyy 7 7 h +3 3 zzza 3 3 i +3 3 zzzz 3 3 i +3 3 zzzz 3 3 i 7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h -3 2 uuuw 3 3 i -3 2 uuua 3 3 i -3 3 zzzz 3 3 i -3 3 zyxw 3 3 i -3 3 zzza 3 3 i -3 3 zyxa 3 3 i +7 8 xxxxx 7 7 h execute stmt; a b c d e f -3 2 uuuw 3 3 i 3 2 uuua 3 3 i -3 3 zzzz 3 3 i +3 2 uuua 3 3 i +3 2 uuuw 3 3 i +3 2 uuuw 3 3 i +3 3 zyxa 3 3 i +3 3 zyxa 3 3 i +3 3 zyxw 3 3 i 3 3 zyxw 3 3 i 3 3 zzza 3 3 i -3 3 zyxa 3 3 i -7 7 xxxyy 7 7 h +3 3 zzza 3 3 i +3 3 zzzz 3 3 i +3 3 zzzz 3 3 i 7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h -3 2 uuuw 3 3 i -3 2 uuua 3 3 i -3 3 zzzz 3 3 i -3 3 zyxw 3 3 i -3 3 zzza 3 3 i -3 3 zyxa 3 3 i +7 8 xxxxx 7 7 h deallocate prepare stmt; insert into t1 select * from t1; # join order: (t2,t1) with ref access of t1 @@ -2739,6 +2770,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2748,7 +2780,9 @@ EXPLAIN "key": "idx1", "key_length": "5", "used_key_parts": ["d"], + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 6.730769157, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and octet_length(t2.f) = 1", @@ -2764,7 +2798,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.d"], + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2774,14 +2810,14 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; a b c d e f -7 7 xxxyy 7 7 h +7 7 xxxya 7 7 h 7 7 xxxya 7 7 h 7 7 xxxyy 7 7 h -7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h +7 8 xxxxa 7 7 h 7 8 xxxxa 7 7 h 7 8 xxxxx 7 7 h -7 8 xxxxa 7 7 h +7 8 xxxxx 7 7 h alter table t2 drop index idx1, drop index idx2, add index idx3(d,e); # join order: (t2,t1) with ref access of t1 # range access to t2 by 2-component keys for index idx3 @@ -2796,6 +2832,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2805,7 +2842,9 @@ EXPLAIN "key": "idx3", "key_length": "10", "used_key_parts": ["d", "e"], + "loops": 1, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and octet_length(t2.f) = 1", @@ -2821,7 +2860,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.d"], + "loops": 5, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2852,6 +2893,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2861,7 +2903,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 15, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a is not null", "mrr_type": "Rowid-ordered scan" @@ -2876,7 +2920,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "loops": 15, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t2.e) in ((4,t1.a + 1),(7,t1.a + 1),(8,t1.a + 1)) and octet_length(t2.f) = 1" } @@ -2887,22 +2933,22 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((4,d+1),(7,d+1),(8,d+1)) and length(f) = 1; a b c d e f -4 5 ww 4 5 a -7 8 xxxxx 7 8 b -4 3 zyx 4 5 a -7 7 xxxyy 7 8 b -4 5 wa 4 5 a -7 8 xxxxa 7 8 b 4 3 zya 4 5 a -7 7 xxxya 7 8 b -4 5 ww 4 5 a -7 8 xxxxx 7 8 b -4 3 zyx 4 5 a -7 7 xxxyy 7 8 b -4 5 wa 4 5 a -7 8 xxxxa 7 8 b 4 3 zya 4 5 a +4 3 zyx 4 5 a +4 3 zyx 4 5 a +4 5 wa 4 5 a +4 5 wa 4 5 a +4 5 ww 4 5 a +4 5 ww 4 5 a 7 7 xxxya 7 8 b +7 7 xxxya 7 8 b +7 7 xxxyy 7 8 b +7 7 xxxyy 7 8 b +7 8 xxxxa 7 8 b +7 8 xxxxa 7 8 b +7 8 xxxxx 7 8 b +7 8 xxxxx 7 8 b # join order: (t1,t2) with ref access of t2 # no range access explain select * from t1,t2 @@ -2916,13 +2962,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", "possible_keys": ["idx"], + "loops": 1, "rows": 144, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a is not null" } @@ -2936,7 +2985,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "loops": 144, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),((7,7)),((8,8))) and octet_length(t2.f) = 1" } @@ -2947,14 +2998,14 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((e,d+1),(7,7),(8,8)) and length(f) = 1; a b c d e f -7 8 xxxxx 7 7 h +7 7 xxxya 7 7 h +7 7 xxxya 7 7 h +7 7 xxxyy 7 7 h 7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h -7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h -7 7 xxxyy 7 7 h 7 8 xxxxa 7 7 h -7 7 xxxya 7 7 h +7 8 xxxxx 7 7 h +7 8 xxxxx 7 7 h # join order: (t1,t2) with ref access of t2 # range access to t1 by 1-component keys for index idx explain select * from t1,t2 @@ -2970,6 +3021,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2979,7 +3031,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a is not null", "attached_condition": "(t1.a,2) in (((2,2)),((7,7)),((8,8))) and octet_length(t1.c) = 1", @@ -2995,7 +3049,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "loops": 12, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "octet_length(t2.f) = 1" } @@ -3054,6 +3110,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -3076,7 +3133,9 @@ EXPLAIN "key": "idx", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 12, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a is not null", "attached_condition": "(t1.a,1 + 1) in (((2,2)),((7,7)),((8,8))) and octet_length(t1.c) = 1", @@ -3092,7 +3151,9 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "ref": ["test.t1.a"], + "loops": 12, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "octet_length(t2.f) = 1" } @@ -3370,7 +3431,7 @@ insert into t2 select A.a + B.a*10 + C.a*100 from ten A, ten B,ten C where A.a + # expected type=range, rows=1487 , reason=using index dives analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198); id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 range a a 5 NULL 1487 1199.00 100.00 100.00 Using where; Using index +1 SIMPLE t1 index a a 5 NULL 2000 2000.00 74.35 59.95 Using where; Using index insert into t2 values (200),(201); # expected type=range, rows=201 , reason=using index statistics analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,200,201); diff --git a/mysql-test/main/range_notembedded.result b/mysql-test/main/range_notembedded.result index e1bcc7463d5..7834418bd2b 100644 --- a/mysql-test/main/range_notembedded.result +++ b/mysql-test/main/range_notembedded.result @@ -225,9 +225,10 @@ user_id int(10) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (notification_type_id,item_id,item_parent_id,user_id) ); insert into t1 values (1,1,1,1), (2,2,2,2), (3,3,3,3); +insert into t1 select seq,seq,seq,seq from seq_10_to_30; # Run crashing query id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 2 NULL 3 Using where +1 SIMPLE t1 range PRIMARY PRIMARY 2 NULL 5 Using where drop table t1; # # MDEV-25069: Assertion `root->weight >= ...' failed in SEL_ARG::tree_delete #2 diff --git a/mysql-test/main/range_notembedded.test b/mysql-test/main/range_notembedded.test index 00d16a5d564..5778cdbd82c 100644 --- a/mysql-test/main/range_notembedded.test +++ b/mysql-test/main/range_notembedded.test @@ -122,6 +122,7 @@ CREATE TABLE t1 ( PRIMARY KEY (notification_type_id,item_id,item_parent_id,user_id) ); insert into t1 values (1,1,1,1), (2,2,2,2), (3,3,3,3); +insert into t1 select seq,seq,seq,seq from seq_10_to_30; let $consts=`select group_concat(concat("'",seq,"'")) from seq_1_to_4642`; diff --git a/mysql-test/main/range_vs_index_merge.result b/mysql-test/main/range_vs_index_merge.result index 1729b95a105..19848d6d388 100644 --- a/mysql-test/main/range_vs_index_merge.result +++ b/mysql-test/main/range_vs_index_merge.result @@ -1077,7 +1077,7 @@ EXPLAIN SELECT Name, Country, Population FROM City WHERE (Name='Samara' AND Country='RUS') OR (Name='Seattle' AND Country='USA'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Country,CountryPopulation,CountryName,CityName CountryName,CityName 38,35 NULL 28 Using sort_union(CountryName,CityName); Using where +1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CountryName 38 NULL 28 Using index condition SELECT Name, Country, Population FROM City WHERE (Name='Manila' AND Country='PHL') OR (Name='Addis Abeba' AND Country='ETH') OR @@ -1325,11 +1325,11 @@ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H')) AND (Population >= 100000 AND Population < 120000) ORDER BY Population LIMIT 5; ID Name Country Population +3792 Tartu EST 101246 +518 Basildon GBR 100924 519 Worthing GBR 100000 638 al-Arish EGY 100447 -518 Basildon GBR 100924 707 Marbella ESP 101144 -3792 Tartu EST 101246 SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value Handler_read_first 0 @@ -1750,6 +1750,9 @@ SELECT * FROM t1,t2,t3 WHERE (t2.f3 = 1 OR t3.f1=t2.f1) AND t3.f1 <> t2.f2 AND t3.f2 = t2.f4; f1 f1 f2 f3 f4 f1 f2 DROP TABLE t1,t2,t3; +# +# LP bug #823301: index merge sort union with possible index scan +# CREATE TABLE t1 ( a int, b int, c int, d int, PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c) @@ -1766,7 +1769,7 @@ EXPLAIN SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where +1 SIMPLE t1 range PRIMARY,idx1,idx2 idx1 5 NULL 5 Using index condition; Using where SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; a b c d @@ -1780,7 +1783,7 @@ EXPLAIN SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where +1 SIMPLE t1 range PRIMARY,idx1,idx2 idx1 5 NULL 5 Using index condition; Using where SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; a b c d @@ -1894,37 +1897,6 @@ INDEX (Percentage) DROP INDEX Country ON City; CREATE INDEX CountryName ON City(Country,Name); CREATE INDEX Name ON City(Name); -select * from City -where -Country='FIN' AND Name IN ('Lahti','Imatra') OR -Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR -Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR -Country='DEU' AND Name IN ('Berlin', 'Bonn') OR -Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR -Country='PRT' AND Name IN ('Braga', 'Porto') OR -Country='FRA' AND Name IN ('Paris', 'Marcel') OR -Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR -Country='NOR' AND Name IN ('Oslo', 'Bergen') OR -Country='ITA' AND Name IN ('Napoli', 'Venezia'); -ID Name Country Population -175 Antwerpen BEL 446525 -176 Gent BEL 224180 -3068 Berlin DEU 3386667 -3087 Bonn DEU 301048 -3242 Lahti FIN 96921 -2974 Paris FRA 2125246 -1466 Napoli ITA 1002619 -1474 Venezia ITA 277305 -2808 Bergen NOR 230948 -2807 Oslo NOR 508726 -2928 Warszawa POL 1615369 -2931 Wroclaw POL 636765 -2918 Braga PRT 90535 -2915 Porto PRT 273060 -3580 Moscow RUS 8389200 -3581 St Petersburg RUS 4694000 -3048 Stockholm SWE 750348 -3051 Uppsala SWE 189569 explain select * from City where Country='FIN' AND Name IN ('Lahti','Imatra') OR @@ -1939,5 +1911,36 @@ Country='NOR' AND Name IN ('Oslo', 'Bergen') OR Country='ITA' AND Name IN ('Napoli', 'Venezia'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range CountryName,Name CountryName 38 NULL 20 Using index condition +select * from City +where +Country='FIN' AND Name IN ('Lahti','Imatra') OR +Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR +Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR +Country='DEU' AND Name IN ('Berlin', 'Bonn') OR +Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR +Country='PRT' AND Name IN ('Braga', 'Porto') OR +Country='FRA' AND Name IN ('Paris', 'Marcel') OR +Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR +Country='NOR' AND Name IN ('Oslo', 'Bergen') OR +Country='ITA' AND Name IN ('Napoli', 'Venezia'); +ID Name Country Population +1466 Napoli ITA 1002619 +1474 Venezia ITA 277305 +175 Antwerpen BEL 446525 +176 Gent BEL 224180 +2807 Oslo NOR 508726 +2808 Bergen NOR 230948 +2915 Porto PRT 273060 +2918 Braga PRT 90535 +2928 Warszawa POL 1615369 +2931 Wroclaw POL 636765 +2974 Paris FRA 2125246 +3048 Stockholm SWE 750348 +3051 Uppsala SWE 189569 +3068 Berlin DEU 3386667 +3087 Bonn DEU 301048 +3242 Lahti FIN 96921 +3580 Moscow RUS 8389200 +3581 St Petersburg RUS 4694000 DROP DATABASE world; set session optimizer_switch='index_merge_sort_intersection=default'; diff --git a/mysql-test/main/range_vs_index_merge.test b/mysql-test/main/range_vs_index_merge.test index 38b643c0b13..14d75b88bfa 100644 --- a/mysql-test/main/range_vs_index_merge.test +++ b/mysql-test/main/range_vs_index_merge.test @@ -659,7 +659,7 @@ let $cond = (Name='Lugansk' AND Country='UKR') OR (Name='Caracas' AND Country='VEN') OR (Name='Samara' AND Country='RUS') OR -(Name='Seattle' AND Country='USA'); +(Name='Seattle' AND Country='USA'); eval EXPLAIN SELECT Name, Country, Population FROM City WHERE @@ -714,6 +714,7 @@ SELECT * FROM City ORDER BY Population LIMIT 5; FLUSH STATUS; +--sorted_result SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H')) AND (Population >= 100000 AND Population < 120000) @@ -1174,9 +1175,9 @@ SELECT * FROM t1,t2,t3 DROP TABLE t1,t2,t3; -# -# LP bug #823301: index merge sort union with possible index scan -# +--echo # +--echo # LP bug #823301: index merge sort union with possible index scan +--echo # CREATE TABLE t1 ( a int, b int, c int, d int, @@ -1192,12 +1193,14 @@ SET SESSION optimizer_switch='index_merge_sort_union=off'; EXPLAIN SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; +--sorted_result SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; SET SESSION optimizer_switch='index_merge_sort_union=on'; EXPLAIN SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; +--sorted_result SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; SET SESSION optimizer_switch=DEFAULT; @@ -1320,12 +1323,11 @@ where Country='NOR' AND Name IN ('Oslo', 'Bergen') OR Country='ITA' AND Name IN ('Napoli', 'Venezia'); -eval $q; eval explain $q; - +--sorted_result +eval $q; DROP DATABASE world; #the following command must be the last one in the file set session optimizer_switch='index_merge_sort_intersection=default'; - diff --git a/mysql-test/main/range_vs_index_merge_innodb.result b/mysql-test/main/range_vs_index_merge_innodb.result index 79a670aedb2..8e0bf58fbc3 100644 --- a/mysql-test/main/range_vs_index_merge_innodb.result +++ b/mysql-test/main/range_vs_index_merge_innodb.result @@ -1331,11 +1331,11 @@ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H')) AND (Population >= 100000 AND Population < 120000) ORDER BY Population LIMIT 5; ID Name Country Population +3792 Tartu EST 101246 +518 Basildon GBR 100924 519 Worthing GBR 100000 638 al-Arish EGY 100447 -518 Basildon GBR 100924 707 Marbella ESP 101144 -3792 Tartu EST 101246 SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value Handler_read_first 0 @@ -1756,6 +1756,9 @@ SELECT * FROM t1,t2,t3 WHERE (t2.f3 = 1 OR t3.f1=t2.f1) AND t3.f1 <> t2.f2 AND t3.f2 = t2.f4; f1 f1 f2 f3 f4 f1 f2 DROP TABLE t1,t2,t3; +# +# LP bug #823301: index merge sort union with possible index scan +# CREATE TABLE t1 ( a int, b int, c int, d int, PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c) @@ -1772,7 +1775,7 @@ EXPLAIN SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where +1 SIMPLE t1 range PRIMARY,idx1,idx2 idx1 5 NULL 5 Using index condition SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; a b c d @@ -1786,7 +1789,7 @@ EXPLAIN SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where +1 SIMPLE t1 range PRIMARY,idx1,idx2 idx1 5 NULL 5 Using index condition SELECT * FROM t1 WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7; a b c d @@ -1804,7 +1807,7 @@ SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,idx idx 5 NULL 2 Using where; Using index +1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using where SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); @@ -1900,37 +1903,6 @@ INDEX (Percentage) DROP INDEX Country ON City; CREATE INDEX CountryName ON City(Country,Name); CREATE INDEX Name ON City(Name); -select * from City -where -Country='FIN' AND Name IN ('Lahti','Imatra') OR -Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR -Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR -Country='DEU' AND Name IN ('Berlin', 'Bonn') OR -Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR -Country='PRT' AND Name IN ('Braga', 'Porto') OR -Country='FRA' AND Name IN ('Paris', 'Marcel') OR -Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR -Country='NOR' AND Name IN ('Oslo', 'Bergen') OR -Country='ITA' AND Name IN ('Napoli', 'Venezia'); -ID Name Country Population -175 Antwerpen BEL 446525 -2808 Bergen NOR 230948 -3068 Berlin DEU 3386667 -3087 Bonn DEU 301048 -2918 Braga PRT 90535 -176 Gent BEL 224180 -3242 Lahti FIN 96921 -3580 Moscow RUS 8389200 -1466 Napoli ITA 1002619 -2807 Oslo NOR 508726 -2974 Paris FRA 2125246 -2915 Porto PRT 273060 -3581 St Petersburg RUS 4694000 -3048 Stockholm SWE 750348 -3051 Uppsala SWE 189569 -1474 Venezia ITA 277305 -2928 Warszawa POL 1615369 -2931 Wroclaw POL 636765 explain select * from City where Country='FIN' AND Name IN ('Lahti','Imatra') OR @@ -1945,6 +1917,37 @@ Country='NOR' AND Name IN ('Oslo', 'Bergen') OR Country='ITA' AND Name IN ('Napoli', 'Venezia'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range CountryName,Name Name 35 NULL 20 Using index condition; Using where +select * from City +where +Country='FIN' AND Name IN ('Lahti','Imatra') OR +Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR +Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR +Country='DEU' AND Name IN ('Berlin', 'Bonn') OR +Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR +Country='PRT' AND Name IN ('Braga', 'Porto') OR +Country='FRA' AND Name IN ('Paris', 'Marcel') OR +Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR +Country='NOR' AND Name IN ('Oslo', 'Bergen') OR +Country='ITA' AND Name IN ('Napoli', 'Venezia'); +ID Name Country Population +1466 Napoli ITA 1002619 +1474 Venezia ITA 277305 +175 Antwerpen BEL 446525 +176 Gent BEL 224180 +2807 Oslo NOR 508726 +2808 Bergen NOR 230948 +2915 Porto PRT 273060 +2918 Braga PRT 90535 +2928 Warszawa POL 1615369 +2931 Wroclaw POL 636765 +2974 Paris FRA 2125246 +3048 Stockholm SWE 750348 +3051 Uppsala SWE 189569 +3068 Berlin DEU 3386667 +3087 Bonn DEU 301048 +3242 Lahti FIN 96921 +3580 Moscow RUS 8389200 +3581 St Petersburg RUS 4694000 DROP DATABASE world; set session optimizer_switch='index_merge_sort_intersection=default'; set global innodb_stats_persistent= @innodb_stats_persistent_save; diff --git a/mysql-test/main/rowid_filter.result b/mysql-test/main/rowid_filter.result index 8447ed8622f..2312fb593d1 100644 --- a/mysql-test/main/rowid_filter.result +++ b/mysql-test/main/rowid_filter.result @@ -77,6 +77,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -94,7 +95,9 @@ EXPLAIN "rows": 702, "selectivity_pct": 11.69025812 }, + "loops": 1, "rows": 509, + "cost": "COST_REPLACED", "filtered": 11.69025803, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", "attached_condition": "lineitem.l_quantity > 45" @@ -118,6 +121,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -142,9 +146,11 @@ ANALYZE "r_buffer_size": "REPLACED", "r_filling_time_ms": "REPLACED" }, + "loops": 1, "r_loops": 1, "rows": 509, "r_rows": 60, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 11.69025803, @@ -232,6 +238,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -241,7 +248,9 @@ EXPLAIN "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "rows": 509, + "cost": "COST_REPLACED", "filtered": 11.69025803, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", "attached_condition": "lineitem.l_quantity > 45" @@ -265,6 +274,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -276,9 +286,11 @@ ANALYZE "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "r_loops": 1, "rows": 509, "r_rows": 510, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 11.69025803, @@ -359,8 +371,8 @@ FROM orders JOIN lineitem ON o_orderkey=l_orderkey WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND o_totalprice between 200000 and 230000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 98 Using index condition -1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 69 Using index condition +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (2%) Using where; Using rowid filter set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice FROM orders JOIN lineitem ON o_orderkey=l_orderkey WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND @@ -369,37 +381,50 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { - "table_name": "lineitem", + "table_name": "orders", "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "loops": 1, + "rows": 69, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "orders.o_totalprice between 200000 and 230000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", "possible_keys": [ "PRIMARY", "i_l_shipdate", "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_shipdate", + "key": "i_l_orderkey", "key_length": "4", - "used_key_parts": ["l_shipDATE"], - "rows": 98, - "filtered": 100, - "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" - } - }, - { - "table": { - "table_name": "orders", - "access_type": "eq_ref", - "possible_keys": ["PRIMARY", "i_o_totalprice"], - "key": "PRIMARY", - "key_length": "4", - "used_key_parts": ["o_orderkey"], - "ref": ["dbt3_s001.lineitem.l_orderkey"], - "rows": 1, - "filtered": 4.599999905, - "attached_condition": "orders.o_totalprice between 200000 and 230000" + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 98, + "selectivity_pct": 1.631973356 + }, + "loops": 69, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 1.631973386, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" } } ] @@ -410,8 +435,8 @@ FROM orders JOIN lineitem ON o_orderkey=l_orderkey WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND o_totalprice between 200000 and 230000; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 98 98.00 100.00 100.00 Using index condition -1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 4.60 11.22 Using where +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 69 71.00 100.00 100.00 Using index condition +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (2%) 0.15 (2%) 1.63 100.00 Using where; Using rowid filter set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice FROM orders JOIN lineitem ON o_orderkey=l_orderkey WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND @@ -423,49 +448,67 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ { "table": { - "table_name": "lineitem", + "table_name": "orders", "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "loops": 1, + "r_loops": 1, + "rows": 69, + "r_rows": 71, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100, + "index_condition": "orders.o_totalprice between 200000 and 230000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", "possible_keys": [ "PRIMARY", "i_l_shipdate", "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_shipdate", + "key": "i_l_orderkey", "key_length": "4", - "used_key_parts": ["l_shipDATE"], - "r_loops": 1, - "rows": 98, - "r_rows": 98, + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 98, + "selectivity_pct": 1.631973356, + "r_rows": 98, + "r_lookups": 476, + "r_selectivity_pct": 2.31092437, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 69, + "r_loops": 71, + "rows": 4, + "r_rows": 0.154929577, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 100, + "filtered": 1.631973386, "r_filtered": 100, - "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" - } - }, - { - "table": { - "table_name": "orders", - "access_type": "eq_ref", - "possible_keys": ["PRIMARY", "i_o_totalprice"], - "key": "PRIMARY", - "key_length": "4", - "used_key_parts": ["o_orderkey"], - "ref": ["dbt3_s001.lineitem.l_orderkey"], - "r_loops": 98, - "rows": 1, - "r_rows": 1, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 4.599999905, - "r_filtered": 11.2244898, - "attached_condition": "orders.o_totalprice between 200000 and 230000" + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" } } ] @@ -502,6 +545,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -516,7 +560,9 @@ EXPLAIN "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "rows": 98, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" } @@ -530,7 +576,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 98, "rows": 1, + "cost": "COST_REPLACED", "filtered": 4.599999905, "attached_condition": "orders.o_totalprice between 200000 and 230000" } @@ -556,6 +604,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -572,9 +621,11 @@ ANALYZE "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "r_loops": 1, "rows": 98, "r_rows": 98, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -591,9 +642,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 98, "r_loops": 98, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 4.599999905, @@ -627,7 +680,7 @@ l_quantity > 45 AND o_totalprice between 180000 and 230000; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE lineitem range|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 509 (12%) Using index condition; Using where; Using rowid filter -1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (9%) Using where; Using rowid filter set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice FROM orders JOIN lineitem ON o_orderkey=l_orderkey WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND @@ -637,6 +690,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -660,7 +714,9 @@ EXPLAIN "rows": 702, "selectivity_pct": 11.69025812 }, + "loops": 1, "rows": 509, + "cost": "COST_REPLACED", "filtered": 11.69025803, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", "attached_condition": "lineitem.l_quantity > 45" @@ -675,7 +731,17 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rowid_filter": { + "range": { + "key": "i_o_totalprice", + "used_key_parts": ["o_totalprice"] + }, + "rows": 139, + "selectivity_pct": 9.266666667 + }, + "loops": 59.50341382, "rows": 1, + "cost": "COST_REPLACED", "filtered": 9.266666412, "attached_condition": "orders.o_totalprice between 180000 and 230000" } @@ -690,7 +756,7 @@ l_quantity > 45 AND o_totalprice between 180000 and 230000; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE lineitem range|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 509 (12%) 60.00 (11%) 11.69 100.00 Using index condition; Using where; Using rowid filter -1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 9.27 26.67 Using where +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (9%) 0.27 (25%) 9.27 100.00 Using where; Using rowid filter set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice FROM orders JOIN lineitem ON o_orderkey=l_orderkey WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND @@ -703,6 +769,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -733,9 +800,11 @@ ANALYZE "r_buffer_size": "REPLACED", "r_filling_time_ms": "REPLACED" }, + "loops": 1, "r_loops": 1, "rows": 509, "r_rows": 60, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 11.69025803, @@ -753,13 +822,28 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rowid_filter": { + "range": { + "key": "i_o_totalprice", + "used_key_parts": ["o_totalprice"] + }, + "rows": 139, + "selectivity_pct": 9.266666667, + "r_rows": 144, + "r_lookups": 59, + "r_selectivity_pct": 25.42372881, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 59.50341382, "r_loops": 60, "rows": 1, - "r_rows": 1, + "r_rows": 0.266666667, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 9.266666412, - "r_filtered": 26.66666667, + "r_filtered": 100, "attached_condition": "orders.o_totalprice between 180000 and 230000" } } @@ -805,6 +889,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -820,7 +905,9 @@ EXPLAIN "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "rows": 509, + "cost": "COST_REPLACED", "filtered": 11.69025803, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", "attached_condition": "lineitem.l_quantity > 45" @@ -835,7 +922,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 59.50341382, "rows": 1, + "cost": "COST_REPLACED", "filtered": 9.266666412, "attached_condition": "orders.o_totalprice between 180000 and 230000" } @@ -863,6 +952,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -880,9 +970,11 @@ ANALYZE "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "r_loops": 1, "rows": 509, "r_rows": 510, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 11.69025803, @@ -900,9 +992,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 59.50341382, "r_loops": 60, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 9.266666412, @@ -935,6 +1029,14 @@ o_orderkey l_linenumber l_shipdate l_quantity o_totalprice 5829 5 1997-01-31 49 183734.56 5895 2 1997-04-27 47 201419.83 5895 3 1997-03-15 49 201419.83 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT STRAIGHT_JOIN o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM lineitem JOIN orders ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 509 (12%) Using index condition; Using where; Using rowid filter +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (9%) Using where; Using rowid filter set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice FROM orders JOIN lineitem ON o_orderkey=l_orderkey WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND @@ -950,6 +1052,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -959,7 +1062,9 @@ EXPLAIN "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "rows": 69, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "orders.o_totalprice between 200000 and 230000" } @@ -986,7 +1091,9 @@ EXPLAIN "rows": 509, "selectivity_pct": 8.476269775 }, + "loops": 69, "rows": 4, + "cost": "COST_REPLACED", "filtered": 8.476269722, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" } @@ -1012,6 +1119,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1023,9 +1131,11 @@ ANALYZE "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "r_loops": 1, "rows": 69, "r_rows": 71, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1060,9 +1170,11 @@ ANALYZE "r_buffer_size": "REPLACED", "r_filling_time_ms": "REPLACED" }, + "loops": 69, "r_loops": 71, "rows": 4, "r_rows": 0.521126761, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 8.476269722, @@ -1130,6 +1242,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1139,7 +1252,9 @@ EXPLAIN "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "rows": 69, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "orders.o_totalprice between 200000 and 230000" } @@ -1158,7 +1273,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 69, "rows": 4, + "cost": "COST_REPLACED", "filtered": 8.476269722, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" } @@ -1184,6 +1301,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1195,9 +1313,11 @@ ANALYZE "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "r_loops": 1, "rows": 69, "r_rows": 71, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1219,9 +1339,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 69, "r_loops": 71, "rows": 4, "r_rows": 6.704225352, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 8.476269722, @@ -1300,6 +1422,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1315,7 +1438,9 @@ EXPLAIN "key": "i_l_receiptdate", "key_length": "4", "used_key_parts": ["l_receiptDATE"], + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 0.566194832, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" @@ -1330,7 +1455,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 7.466666698, "attached_condition": "orders.o_totalprice between 200000 and 250000" } @@ -1360,6 +1487,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1377,9 +1505,11 @@ ANALYZE "key": "i_l_receiptdate", "key_length": "4", "used_key_parts": ["l_receiptDATE"], + "loops": 1, "r_loops": 1, "rows": 18, "r_rows": 18, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 0.566194832, @@ -1397,9 +1527,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, "r_loops": 7, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 7.466666698, @@ -1437,6 +1569,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1452,7 +1585,9 @@ EXPLAIN "key": "i_l_receiptdate", "key_length": "4", "used_key_parts": ["l_receiptDATE"], + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 0.566194832, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" @@ -1467,7 +1602,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 7.466666698, "attached_condition": "orders.o_totalprice between 200000 and 250000" } @@ -1497,6 +1634,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1514,9 +1652,11 @@ ANALYZE "key": "i_l_receiptdate", "key_length": "4", "used_key_parts": ["l_receiptDATE"], + "loops": 1, "r_loops": 1, "rows": 18, "r_rows": 18, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 0.566194832, @@ -1534,9 +1674,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, "r_loops": 7, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 7.466666698, @@ -1570,7 +1712,7 @@ o_totalprice BETWEEN 200000 AND 220000 AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE orders range PRIMARY,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 Using index condition; Using where -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 Using where +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (3%) Using where; Using rowid filter set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate FROM orders, lineitem WHERE o_orderkey=l_orderkey AND @@ -1581,6 +1723,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1590,7 +1733,9 @@ EXPLAIN "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "rows": 39, + "cost": "COST_REPLACED", "filtered": 3.200000048, "index_condition": "orders.o_totaldiscount between 18000 and 20000", "attached_condition": "orders.o_totalprice between 200000 and 220000" @@ -1606,11 +1751,21 @@ EXPLAIN "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_orderkey", + "key": "PRIMARY", "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 183, + "selectivity_pct": 3.04746045 + }, + "loops": 1.248, "rows": 4, + "cost": "COST_REPLACED", "filtered": 3.047460556, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } @@ -1626,7 +1781,7 @@ o_totalprice BETWEEN 200000 AND 220000 AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE orders range PRIMARY,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 41.00 3.20 2.44 Using index condition; Using where -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.00 3.05 66.67 Using where +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (3%) 4.00 (66%) 3.05 100.00 Using where; Using rowid filter set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate FROM orders, lineitem WHERE o_orderkey=l_orderkey AND @@ -1640,6 +1795,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1651,9 +1807,11 @@ ANALYZE "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "r_loops": 1, "rows": 39, "r_rows": 41, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 3.200000048, @@ -1672,17 +1830,32 @@ ANALYZE "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_orderkey", + "key": "PRIMARY", "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 183, + "selectivity_pct": 3.04746045, + "r_rows": 183, + "r_lookups": 6, + "r_selectivity_pct": 66.66666667, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 1.248, "r_loops": 1, "rows": 4, - "r_rows": 6, + "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 3.047460556, - "r_filtered": 66.66666667, + "r_filtered": 100, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } } @@ -1708,7 +1881,7 @@ o_totalprice BETWEEN 200000 AND 220000 AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE orders range PRIMARY,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 Using index condition; Using where -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate FROM orders, lineitem WHERE o_orderkey=l_orderkey AND @@ -1719,6 +1892,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1728,7 +1902,9 @@ EXPLAIN "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "rows": 39, + "cost": "COST_REPLACED", "filtered": 3.200000048, "index_condition": "orders.o_totaldiscount between 18000 and 20000", "attached_condition": "orders.o_totalprice between 200000 and 220000" @@ -1744,11 +1920,13 @@ EXPLAIN "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_orderkey", + "key": "PRIMARY", "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.248, "rows": 4, + "cost": "COST_REPLACED", "filtered": 3.047460556, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } @@ -1764,7 +1942,7 @@ o_totalprice BETWEEN 200000 AND 220000 AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE orders range PRIMARY,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 41.00 3.20 2.44 Using index condition; Using where -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.00 3.05 66.67 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 3.05 66.67 Using where set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate FROM orders, lineitem WHERE o_orderkey=l_orderkey AND @@ -1778,6 +1956,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1789,9 +1968,11 @@ ANALYZE "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "r_loops": 1, "rows": 39, "r_rows": 41, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 3.200000048, @@ -1810,13 +1991,15 @@ ANALYZE "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_orderkey", + "key": "PRIMARY", "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.248, "r_loops": 1, "rows": 4, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 3.047460556, @@ -1849,7 +2032,7 @@ o_totalprice BETWEEN 200000 AND 220000 AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 Using index condition; Using where -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate FROM v1, lineitem WHERE o_orderkey=l_orderkey AND @@ -1860,6 +2043,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "REPLACED", "nested_loop": [ { "table": { @@ -1874,7 +2058,9 @@ EXPLAIN "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "rows": 39, + "cost": "REPLACED", "filtered": "REPLACED", "index_condition": "orders.o_totaldiscount between 18000 and 20000", "attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'" @@ -1890,11 +2076,13 @@ EXPLAIN "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_orderkey", + "key": "PRIMARY", "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1, "rows": 4, + "cost": "REPLACED", "filtered": "REPLACED", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } @@ -1910,7 +2098,7 @@ o_totalprice BETWEEN 200000 AND 220000 AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 41.00 # 2.44 Using index condition; Using where -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate FROM v1, lineitem WHERE o_orderkey=l_orderkey AND @@ -1924,6 +2112,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1940,9 +2129,11 @@ ANALYZE "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "r_loops": 1, "rows": 39, "r_rows": 41, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": "REPLACED", @@ -1961,13 +2152,15 @@ ANALYZE "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_orderkey", + "key": "PRIMARY", "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": "REPLACED", @@ -1997,7 +2190,7 @@ o_totalprice BETWEEN 200000 AND 220000 AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 Using index condition; Using where -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate FROM v1, lineitem WHERE o_orderkey=l_orderkey AND @@ -2008,6 +2201,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "REPLACED", "nested_loop": [ { "table": { @@ -2022,7 +2216,9 @@ EXPLAIN "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "rows": 39, + "cost": "REPLACED", "filtered": "REPLACED", "index_condition": "orders.o_totaldiscount between 18000 and 20000", "attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'" @@ -2038,11 +2234,13 @@ EXPLAIN "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_orderkey", + "key": "PRIMARY", "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1, "rows": 4, + "cost": "REPLACED", "filtered": "REPLACED", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } @@ -2058,7 +2256,7 @@ o_totalprice BETWEEN 200000 AND 220000 AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 41.00 # 2.44 Using index condition; Using where -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate FROM v1, lineitem WHERE o_orderkey=l_orderkey AND @@ -2072,6 +2270,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -2088,9 +2287,11 @@ ANALYZE "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "r_loops": 1, "rows": 39, "r_rows": 41, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": "REPLACED", @@ -2109,13 +2310,15 @@ ANALYZE "i_l_orderkey", "i_l_orderkey_quantity" ], - "key": "i_l_orderkey", + "key": "PRIMARY", "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": "REPLACED", @@ -2143,700 +2346,3 @@ ALTER TABLE orders DROP COLUMN o_totaldiscount; DROP VIEW v1; DROP DATABASE dbt3_s001; use test; -# -# MDEV-18816: potential range filter for one join table with -# impossible WHERE for another -# -create table t1 ( -pk int not null primary key, c2 varchar(10) , i1 int,key (c2) -) engine=myisam; -insert into t1 values (1,'a',-5),(2,'a',null); -create table t2 ( -pk int, i1 int, c1 varchar(30) , key c1 (c1(30)), key i1 (i1) -) engine=myisam; -insert into t2 values -(1,-5,'a'),(2,null,'a'),(3,null,'a'),(4,null,'a'),(5,5,'a'),(6,null,'a'), -(7,4,'a'),(8,55,'a'),(9,null,'a'),(10,null,'a'),(11,null,'a'),(12,-5,'a'), -(13,-5,'a'),(14,null,'a'),(15,null,'a'),(16,-5,'a'),(17,-5,'a'); -select 1 -from t1 -left join -t2 join t1 as t1_a on t2.i1 = t1_a.pk -on t1.c2 = t2.c1 -where t1_a.pk is null and t1_a.i1 != 3; -1 -explain extended select 1 -from t1 -left join -t2 join t1 as t1_a on t2.i1 = t1_a.pk -on t1.c2 = t2.c1 -where t1_a.pk is null and t1_a.i1 != 3; -id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -Warnings: -Note 1003 select 1 AS `1` from `test`.`t1` join `test`.`t2` join `test`.`t1` `t1_a` where 0 -drop table t1,t2; -# -# MDEV-18640: TABLE::prune_range_rowid_filters: Conditional jump or -# move depends on uninitialized value -# -CREATE TABLE t1 ( -pk INT, i INT, PRIMARY KEY (pk), KEY (pk,i) -) ENGINE=MyISAM; -INSERT INTO t1 VALUES (1,10), (7,70), (2,20); -SELECT * FROM t1 WHERE pk < 5; -pk i -1 10 -2 20 -DROP TABLE t1; -# -# MDEV-18956: Possible rowid filter for subquery for which -# in_to_exists strategy has been chosen -# -CREATE TABLE t1 (pk int) engine=myisam ; -INSERT INTO t1 VALUES (1),(2); -CREATE TABLE t2 ( -pk int auto_increment PRIMARY KEY, -i1 int, i2 int, c2 varchar(1), -KEY (i1), KEY (i2) -) engine=myisam; -INSERT INTO t2 VALUES -(1,8,6,'t'),(2,5,7,'i'),(3,4,4,'h'),(4,207,38,'d'),(5,183,206,'b'), -(6,7,null,'o'),(7,1,2,'j'),(8,17,36,'s'),(9,4,5,'q'),(10,0,6,'l'), -(11,1,9,'j'),(12,5,6,'y'),(13,null,0,'i'),(14,7,7,'x'),(15,5,2,'u'); -SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); -pk -EXPLAIN EXTENDED -SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING -2 SUBQUERY t2 ref i1,i2 i1 5 const 1 100.00 Using index condition; Using where -Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` having 0 -DROP TABLE t1,t2; -# -# MDEV-19255: rowid range filter built for range condition -# that uses in expensive subquery -# -CREATE TABLE t1 ( -pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(a1), KEY(b1) -) ENGINE=MyISAM; -INSERT INTO t1 VALUES -(10,0,'z'),(11,3,'j'),(12,8,'f'),(13,8,'p'),(14,6,'w'),(15,0,'c'),(16,1,'j'), -(17,1,'f'),(18,5,'v'),(19,3,'f'),(20,2,'q'),(21,8,'y'),(22,0,'a'),(23,9,'w'), -(24,3,'e'),(25,1,'b'),(26,9,'r'),(27,2,'k'),(28,5,'c'),(29,3,'k'),(30,9,'b'), -(31,8,'j'),(32,1,'t'),(33,8,'n'),(34,3,'z'),(35,0,'u'),(36,3,'a'),(37,3,'g'), -(38,1,'f'),(39,6,'p'),(40,6,'m'),(41,6,'t'),(42,7,'i'),(43,4,'h'),(44,3,'d'), -(45,2,'b'),(46,1,'o'),(47,2,'j'),(48,6,'s'),(49,5,'q'),(50,6,'l'),(51,9,'j'), -(52,6,'y'),(53,0,'i'),(54,7,'x'),(55,2,'u'),(56,6,'t'),(57,4,'b'),(58,5,'m'), -(59,4,'x'),(60,8,'x'),(61,6,'v'),(62,8,'m'),(63,4,'j'),(64,8,'z'),(65,2,'a'), -(66,9,'i'),(67,4,'g'),(68,8,'h'),(69,1,'p'),(70,8,'a'),(71,0,'x'),(72,2,'s'), -(73,6,'k'),(74,0,'m'),(75,6,'e'),(76,9,'y'),(77,7,'d'),(78,7,'w'),(79,6,'y'), -(80,9,'s'),(81,9,'x'),(82,6,'l'),(83,9,'f'),(84,8,'x'),(85,1,'p'),(86,7,'y'), -(87,6,'p'),(88,1,'g'),(89,3,'c'),(90,5,'h'),(91,3,'p'),(92,2,'b'),(93,1,NULL), -(94,3,NULL),(95,2,'y'),(96,7,'s'),(97,7,'x'),(98,6,'i'),(99,9,'t'),(100,5,'j'), -(101,0,'u'),(102,7,'r'),(103,2,'x'),(104,8,'e'),(105,8,'i'),(106,5,'q'), -(107,8,'z'),(108,3,'k'),(109,65,NULL); -CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 INT, b2 VARCHAR(1)) ENGINE=MyISAM; -INSERT INTO t2 VALUES (1,1,'i'); -INSERT INTO t2 SELECT * FROM t1; -INSERT INTO t1 SELECT pk1+200, a1, b1 FROM t1; -INSERT INTO t1 SELECT pk1+400, a1, b1 FROM t1; -ANALYZE TABLE t1,t2 PERSISTENT FOR ALL; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status OK -test.t2 analyze status Engine-independent statistics collected -test.t2 analyze status OK -SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 ) -WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); -pk1 a1 b1 pk2 a2 b2 -17 1 f 16 1 j -37 3 g 36 3 a -105 8 i 104 8 e -EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 ) -WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 101 100.00 Using where -1 PRIMARY t1 ref a1,b1 a1 5 test.t2.a2 36 28.75 Using where -2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition -Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`pk2` AS `pk2`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a1` = `test`.`t2`.`a2` and `test`.`t1`.`b1` <= (/* select#2 */ select max(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`pk2` <= 1) and `test`.`t1`.`pk1` + 1 = `test`.`t2`.`pk2` + 2 -EXPLAIN FORMAT=JSON SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 ) -WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); -EXPLAIN -{ - "query_block": { - "select_id": 1, - "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "ALL", - "rows": 101, - "filtered": 100, - "attached_condition": "t2.a2 is not null" - } - }, - { - "table": { - "table_name": "t1", - "access_type": "ref", - "possible_keys": ["a1", "b1"], - "key": "a1", - "key_length": "5", - "used_key_parts": ["a1"], - "ref": ["test.t2.a2"], - "rows": 36, - "filtered": 28.75, - "attached_condition": "t1.b1 <= (subquery#2) and t1.pk1 + 1 = t2.pk2 + 2" - } - } - ], - "subqueries": [ - { - "query_block": { - "select_id": 2, - "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "range", - "possible_keys": ["PRIMARY"], - "key": "PRIMARY", - "key_length": "4", - "used_key_parts": ["pk2"], - "rows": 1, - "filtered": 100, - "index_condition": "t2.pk2 <= 1" - } - } - ] - } - } - ] - } -} -DROP TABLE t1,t2; -# -# MDEV-21794: Optimizer flag rowid_filter leads to long query -# -create table t10(a int); -insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -create table t11(a int); -insert into t11 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C; -CREATE TABLE t1 ( -el_id int(10) unsigned NOT NULL , -el_index blob NOT NULL, -el_index_60 varbinary(60) NOT NULL, -filler blob, -PRIMARY KEY (el_id), -KEY el_index (el_index(60)), -KEY el_index_60 (el_index_60,el_id) -); -insert into t1 -select -A.a+1000*B.a, -A.a+1000*B.a + 10000, -A.a+1000*B.a + 10000, -'filler-data-filler-data' -from -t11 A, t10 B; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze Warning Engine-independent statistics are not collected for column 'el_index' -test.t1 analyze Warning Engine-independent statistics are not collected for column 'filler' -test.t1 analyze status Table is already up to date -# This must not use rowid_filter with key=el_index|el_index_60: -explain -select * from t1 -where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range el_index,el_index_60 el_index 62 NULL 645 Using where -drop table t10, t11, t1; -# -# MDEV-22160: SIGSEGV in st_join_table::save_explain_data on SELECT -# -set @save_optimizer_switch= @@optimizer_switch; -SET @@optimizer_switch="index_merge_sort_union=OFF"; -CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b)); -INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4); -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -ANALYZE table t1 PERSISTENT FOR ALL; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status OK -explain -SELECT * FROM t1 WHERE a > 0 AND b=0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range|filter a,b a|b 5|5 NULL 77 (34%) Using index condition; Using where; Using rowid filter -SELECT * FROM t1 WHERE a > 0 AND b=0; -a b -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -drop table t1; -SET @@optimizer_switch=@save_optimizer_switch; -# -# MDEV-28846: Poor performance when rowid filter contains no elements -# -create table t1 ( -pk int primary key auto_increment, -nm varchar(32), -fl1 tinyint default 0, -fl2 tinyint default 0, -index idx1(nm, fl1), -index idx2(fl2) -) engine=myisam; -create table name ( -pk int primary key auto_increment, -nm bigint -) engine=myisam; -create table flag2 ( -pk int primary key auto_increment, -fl2 tinyint -) engine=myisam; -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -select '500%' as a; -a -500% -set optimizer_switch='rowid_filter=on'; -explain -select * from t1 where nm like '500%' AND fl2 = 0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where -analyze format=json -select * from t1 where nm like '500%' AND fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "range", - "possible_keys": ["idx1", "idx2"], - "key": "idx1", - "key_length": "35", - "used_key_parts": ["nm"], - "r_loops": 1, - "rows": 1, - "r_rows": 1, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 49.20000076, - "r_filtered": 100, - "index_condition": "t1.nm like '500%'", - "attached_condition": "t1.fl2 = 0" - } - } - ] - } -} -select * from t1 where nm like '500%' AND fl2 = 0; -pk nm fl1 fl2 -517 500 0 0 -truncate table name; -truncate table flag2; -truncate table t1; -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -set optimizer_switch='rowid_filter=off'; -explain -select * from t1 where nm like '500%' AND fl2 = 0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where -analyze format=json -select * from t1 where nm like '500%' AND fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "range", - "possible_keys": ["idx1", "idx2"], - "key": "idx1", - "key_length": "35", - "used_key_parts": ["nm"], - "r_loops": 1, - "rows": 1, - "r_rows": 1, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 49.20000076, - "r_filtered": 100, - "index_condition": "t1.nm like '500%'", - "attached_condition": "t1.fl2 = 0" - } - } - ] - } -} -select * from t1 where nm like '500%' AND fl2 = 0; -pk nm fl1 fl2 -517 500 0 0 -truncate table name; -truncate table flag2; -truncate table t1; -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 10 from seq_1_to_1000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -select '607%' as a; -a -607% -set optimizer_switch='rowid_filter=on'; -explain -select * from t1 where nm like '607%' AND fl2 = 0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where -select * from t1 where nm like '607%' AND fl2 = 0; -pk nm fl1 fl2 -721 607 0 0 -truncate table name; -truncate table flag2; -truncate table t1; -insert into name(nm) select seq from seq_1_to_10000 order by rand(17); -insert into flag2(fl2) select seq mod 100 from seq_1_to_10000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -select '75%' as a; -a -75% -set optimizer_switch='rowid_filter=on'; -explain -select * from t1 where nm like '75%' AND fl2 = 0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref|filter idx1,idx2 idx2|idx1 2|35 const 55 (1%) Using where; Using rowid filter -analyze format=json -select * from t1 where nm like '75%' AND fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ref", - "possible_keys": ["idx1", "idx2"], - "key": "idx2", - "key_length": "2", - "used_key_parts": ["fl2"], - "ref": ["const"], - "rowid_filter": { - "range": { - "key": "idx1", - "used_key_parts": ["nm"] - }, - "rows": 115, - "selectivity_pct": 1.15, - "r_rows": 111, - "r_lookups": 100, - "r_selectivity_pct": 2, - "r_buffer_size": "REPLACED", - "r_filling_time_ms": "REPLACED" - }, - "r_loops": 1, - "rows": 55, - "r_rows": 2, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 1.149999976, - "r_filtered": 100, - "attached_condition": "t1.nm like '75%'" - } - } - ] - } -} -select * from t1 where nm like '75%' AND fl2 = 0; -pk nm fl1 fl2 -4543 7503 0 0 -7373 7518 0 0 -drop table name, flag2; -drop table t1; -create table t1 ( -pk int primary key auto_increment, -nm char(255), -fl1 tinyint default 0, -fl2 int default 0, -index idx1(nm, fl1), -index idx2(fl2) -) engine=myisam; -create table name ( -pk int primary key auto_increment, -nm bigint -) engine=myisam; -create table flag2 ( -pk int primary key auto_increment, -fl2 int -) engine=myisam; -insert into name(nm) select seq from seq_1_to_10000 order by rand(17); -insert into flag2(fl2) select seq mod 10 from seq_1_to_10000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -select * from t1 -where -( -nm like '3400%' or nm like '3402%' or nm like '3403%' or -nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or -nm like '3409%' or -nm like '3411%' or nm like '3412%' or nm like '3413%' or -nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or -nm like '3418%' or nm like '3419%' or -nm like '3421%' or nm like '3422%' or nm like '3423%' or -nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or -nm like '3428%' or nm like '3429%' or -nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or -nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or -nm like '3439%' or -nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or -nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or -nm like '3448%' -) and fl2 = 0; -pk nm fl1 fl2 -analyze format=json select * from t1 -where -( -nm like '3400%' or nm like '3402%' or nm like '3403%' or -nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or -nm like '3409%' or -nm like '3411%' or nm like '3412%' or nm like '3413%' or -nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or -nm like '3418%' or nm like '3419%' or -nm like '3421%' or nm like '3422%' or nm like '3423%' or -nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or -nm like '3428%' or nm like '3429%' or -nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or -nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or -nm like '3439%' or -nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or -nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or -nm like '3448%' -) and fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ref", - "possible_keys": ["idx1", "idx2"], - "key": "idx2", - "key_length": "5", - "used_key_parts": ["fl2"], - "ref": ["const"], - "rowid_filter": { - "range": { - "key": "idx1", - "used_key_parts": ["nm"] - }, - "rows": 44, - "selectivity_pct": 0.44, - "r_rows": 44, - "r_lookups": 1000, - "r_selectivity_pct": 0, - "r_buffer_size": "REPLACED", - "r_filling_time_ms": "REPLACED" - }, - "r_loops": 1, - "rows": 863, - "r_rows": 0, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 0.439999998, - "r_filtered": 100, - "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'" - } - } - ] - } -} -create table t0 select * from t1 where nm like '34%'; -delete from t1 using t1,t0 where t1.nm=t0.nm; -analyze format=json select * from t1 -where -( -nm like '3400%' or nm like '3402%' or nm like '3403%' or -nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or -nm like '3409%' or -nm like '3411%' or nm like '3412%' or nm like '3413%' or -nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or -nm like '3418%' or nm like '3419%' or -nm like '3421%' or nm like '3422%' or nm like '3423%' or -nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or -nm like '3428%' or nm like '3429%' or -nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or -nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or -nm like '3439%' or -nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or -nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or -nm like '3448%' -) and fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ref", - "possible_keys": ["idx1", "idx2"], - "key": "idx2", - "key_length": "5", - "used_key_parts": ["fl2"], - "ref": ["const"], - "rowid_filter": { - "range": { - "key": "idx1", - "used_key_parts": ["nm"] - }, - "rows": 44, - "selectivity_pct": 0.44, - "r_rows": 0, - "r_lookups": 0, - "r_selectivity_pct": 0, - "r_buffer_size": "REPLACED", - "r_filling_time_ms": "REPLACED" - }, - "r_loops": 1, - "rows": 853, - "r_rows": 0, - "filtered": 0.439999998, - "r_filtered": 100, - "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'" - } - } - ] - } -} -drop table t0; -set optimizer_switch='rowid_filter=default'; -drop table name, flag2; -drop table t1; -set @@use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/main/rowid_filter.test b/mysql-test/main/rowid_filter.test index a2543e197ca..bbf0334fbbf 100644 --- a/mysql-test/main/rowid_filter.test +++ b/mysql-test/main/rowid_filter.test @@ -55,6 +55,7 @@ SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem l_quantity > 45; eval $with_filter EXPLAIN $q1; +--source include/explain-no-costs.inc eval $with_filter EXPLAIN FORMAT=JSON $q1; eval $with_filter ANALYZE $q1; --source include/analyze-format.inc @@ -63,6 +64,7 @@ eval $with_filter ANALYZE FORMAT=JSON $q1; eval $with_filter $q1; eval $without_filter EXPLAIN $q1; +--source include/explain-no-costs.inc eval $without_filter EXPLAIN FORMAT=JSON $q1; eval $without_filter ANALYZE $q1; --source include/analyze-format.inc @@ -77,6 +79,7 @@ SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice o_totalprice between 200000 and 230000; eval $with_filter EXPLAIN $q2; +--source include/explain-no-costs.inc eval $with_filter EXPLAIN FORMAT=JSON $q2; eval $with_filter ANALYZE $q2; --source include/analyze-format.inc @@ -85,6 +88,7 @@ eval $with_filter ANALYZE FORMAT=JSON $q2; eval $with_filter $q2; eval $without_filter EXPLAIN $q2; +--source include/explain-no-costs.inc eval $without_filter EXPLAIN FORMAT=JSON $q2; eval $without_filter ANALYZE $q2; --source include/analyze-format.inc @@ -100,6 +104,7 @@ SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice o_totalprice between 180000 and 230000; eval $with_filter EXPLAIN $q3; +--source include/explain-no-costs.inc eval $with_filter EXPLAIN FORMAT=JSON $q3; eval $with_filter ANALYZE $q3; --source include/analyze-format.inc @@ -108,6 +113,7 @@ eval $with_filter ANALYZE FORMAT=JSON $q3; eval $with_filter $q3; eval $without_filter EXPLAIN $q3; +--source include/explain-no-costs.inc eval $without_filter EXPLAIN FORMAT=JSON $q3; eval $without_filter ANALYZE $q3; --source include/analyze-format.inc @@ -115,6 +121,13 @@ eval $without_filter ANALYZE FORMAT=JSON $q3; --sorted_result eval $without_filter $q3; +# Check different optimization +eval $with_filter EXPLAIN SELECT STRAIGHT_JOIN o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice + FROM lineitem JOIN orders ON o_orderkey=l_orderkey + WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND + l_quantity > 45 AND + o_totalprice between 180000 and 230000; + let $q4= SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice FROM orders JOIN lineitem ON o_orderkey=l_orderkey @@ -122,6 +135,7 @@ SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice o_totalprice between 200000 and 230000; eval $with_filter EXPLAIN $q4; +--source include/explain-no-costs.inc eval $with_filter EXPLAIN FORMAT=JSON $q4; eval $with_filter ANALYZE $q4; --source include/analyze-format.inc @@ -130,6 +144,7 @@ eval $with_filter ANALYZE FORMAT=JSON $q4; eval $with_filter $q4; eval $without_filter EXPLAIN $q4; +--source include/explain-no-costs.inc eval $without_filter EXPLAIN FORMAT=JSON $q4; eval $without_filter ANALYZE $q4; --source include/analyze-format.inc @@ -155,6 +170,7 @@ WHERE o_orderkey=l_orderkey AND o_totalprice BETWEEN 200000 AND 250000; eval $with_filter EXPLAIN $q5; +--source include/explain-no-costs.inc eval $with_filter EXPLAIN FORMAT=JSON $q5; eval $with_filter ANALYZE $q5; --source include/analyze-format.inc @@ -163,6 +179,7 @@ eval $with_filter ANALYZE FORMAT=JSON $q5; eval $with_filter $q5; eval $without_filter EXPLAIN $q5; +--source include/explain-no-costs.inc eval $without_filter EXPLAIN FORMAT=JSON $q5; eval $without_filter ANALYZE $q5; --source include/analyze-format.inc @@ -188,6 +205,7 @@ WHERE o_orderkey=l_orderkey AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; eval $with_filter EXPLAIN $q6; +--source include/explain-no-costs.inc eval $with_filter EXPLAIN FORMAT=JSON $q6; eval $with_filter ANALYZE $q6; --source include/analyze-format.inc @@ -196,6 +214,7 @@ eval $with_filter ANALYZE FORMAT=JSON $q6; eval $with_filter $q6; eval $without_filter EXPLAIN $q6; +--source include/explain-no-costs.inc eval $without_filter EXPLAIN FORMAT=JSON $q6; eval $without_filter ANALYZE $q6; --source include/analyze-format.inc @@ -216,21 +235,21 @@ WHERE o_orderkey=l_orderkey AND l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; eval $with_filter EXPLAIN $q7; ---replace_regex /"filtered": [0-9e\.\-+]*,/"filtered": "REPLACED",/ +--source include/explain-no-costs-filtered.inc eval $with_filter EXPLAIN FORMAT=JSON $q7; --replace_column 11 # eval $with_filter ANALYZE $q7; ---replace_regex /("(r_(total|table|other)_time_ms|r_buffer_size|r_filling_time_ms|filtered)": )[^, \n]*/\1"REPLACED"/ +--source include/analyze-no-filtered.inc eval $with_filter ANALYZE FORMAT=JSON $q7; --sorted_result eval $with_filter $q7; eval $without_filter EXPLAIN $q7; ---replace_regex /"filtered": [0-9e\.\-+]*,/"filtered": "REPLACED",/ +--source include/explain-no-costs-filtered.inc eval $without_filter EXPLAIN FORMAT=JSON $q7; --replace_column 11 # eval $without_filter ANALYZE $q7; ---replace_regex /("(r_(total|table|other)_time_ms|r_buffer_size|r_filling_time_ms|filtered)": )[^, \n]*/\1"REPLACED"/ +--source include/analyze-no-filtered.inc eval $without_filter ANALYZE FORMAT=JSON $q7; --sorted_result eval $without_filter $q7; @@ -243,371 +262,3 @@ DROP VIEW v1; DROP DATABASE dbt3_s001; use test; - ---echo # ---echo # MDEV-18816: potential range filter for one join table with ---echo # impossible WHERE for another ---echo # - -create table t1 ( - pk int not null primary key, c2 varchar(10) , i1 int,key (c2) -) engine=myisam; -insert into t1 values (1,'a',-5),(2,'a',null); - -create table t2 ( - pk int, i1 int, c1 varchar(30) , key c1 (c1(30)), key i1 (i1) -) engine=myisam; -insert into t2 values - (1,-5,'a'),(2,null,'a'),(3,null,'a'),(4,null,'a'),(5,5,'a'),(6,null,'a'), - (7,4,'a'),(8,55,'a'),(9,null,'a'),(10,null,'a'),(11,null,'a'),(12,-5,'a'), - (13,-5,'a'),(14,null,'a'),(15,null,'a'),(16,-5,'a'),(17,-5,'a'); - -let $q= -select 1 - from t1 - left join - t2 join t1 as t1_a on t2.i1 = t1_a.pk - on t1.c2 = t2.c1 -where t1_a.pk is null and t1_a.i1 != 3; - -eval $q; -eval explain extended $q; - -drop table t1,t2; - ---echo # ---echo # MDEV-18640: TABLE::prune_range_rowid_filters: Conditional jump or ---echo # move depends on uninitialized value ---echo # - -CREATE TABLE t1 ( - pk INT, i INT, PRIMARY KEY (pk), KEY (pk,i) -) ENGINE=MyISAM; -INSERT INTO t1 VALUES (1,10), (7,70), (2,20); - -SELECT * FROM t1 WHERE pk < 5; - -DROP TABLE t1; - ---echo # ---echo # MDEV-18956: Possible rowid filter for subquery for which ---echo # in_to_exists strategy has been chosen ---echo # - -CREATE TABLE t1 (pk int) engine=myisam ; -INSERT INTO t1 VALUES (1),(2); - -CREATE TABLE t2 ( - pk int auto_increment PRIMARY KEY, - i1 int, i2 int, c2 varchar(1), - KEY (i1), KEY (i2) -) engine=myisam; - -INSERT INTO t2 VALUES - (1,8,6,'t'),(2,5,7,'i'),(3,4,4,'h'),(4,207,38,'d'),(5,183,206,'b'), - (6,7,null,'o'),(7,1,2,'j'),(8,17,36,'s'),(9,4,5,'q'),(10,0,6,'l'), - (11,1,9,'j'),(12,5,6,'y'),(13,null,0,'i'),(14,7,7,'x'),(15,5,2,'u'); - -SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); -EXPLAIN EXTENDED -SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); - -DROP TABLE t1,t2; - ---echo # ---echo # MDEV-19255: rowid range filter built for range condition ---echo # that uses in expensive subquery ---echo # - -CREATE TABLE t1 ( - pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(a1), KEY(b1) -) ENGINE=MyISAM; -INSERT INTO t1 VALUES -(10,0,'z'),(11,3,'j'),(12,8,'f'),(13,8,'p'),(14,6,'w'),(15,0,'c'),(16,1,'j'), -(17,1,'f'),(18,5,'v'),(19,3,'f'),(20,2,'q'),(21,8,'y'),(22,0,'a'),(23,9,'w'), -(24,3,'e'),(25,1,'b'),(26,9,'r'),(27,2,'k'),(28,5,'c'),(29,3,'k'),(30,9,'b'), -(31,8,'j'),(32,1,'t'),(33,8,'n'),(34,3,'z'),(35,0,'u'),(36,3,'a'),(37,3,'g'), -(38,1,'f'),(39,6,'p'),(40,6,'m'),(41,6,'t'),(42,7,'i'),(43,4,'h'),(44,3,'d'), -(45,2,'b'),(46,1,'o'),(47,2,'j'),(48,6,'s'),(49,5,'q'),(50,6,'l'),(51,9,'j'), -(52,6,'y'),(53,0,'i'),(54,7,'x'),(55,2,'u'),(56,6,'t'),(57,4,'b'),(58,5,'m'), -(59,4,'x'),(60,8,'x'),(61,6,'v'),(62,8,'m'),(63,4,'j'),(64,8,'z'),(65,2,'a'), -(66,9,'i'),(67,4,'g'),(68,8,'h'),(69,1,'p'),(70,8,'a'),(71,0,'x'),(72,2,'s'), -(73,6,'k'),(74,0,'m'),(75,6,'e'),(76,9,'y'),(77,7,'d'),(78,7,'w'),(79,6,'y'), -(80,9,'s'),(81,9,'x'),(82,6,'l'),(83,9,'f'),(84,8,'x'),(85,1,'p'),(86,7,'y'), -(87,6,'p'),(88,1,'g'),(89,3,'c'),(90,5,'h'),(91,3,'p'),(92,2,'b'),(93,1,NULL), -(94,3,NULL),(95,2,'y'),(96,7,'s'),(97,7,'x'),(98,6,'i'),(99,9,'t'),(100,5,'j'), -(101,0,'u'),(102,7,'r'),(103,2,'x'),(104,8,'e'),(105,8,'i'),(106,5,'q'), -(107,8,'z'),(108,3,'k'),(109,65,NULL); - -CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 INT, b2 VARCHAR(1)) ENGINE=MyISAM; -INSERT INTO t2 VALUES (1,1,'i'); -INSERT INTO t2 SELECT * FROM t1; - -INSERT INTO t1 SELECT pk1+200, a1, b1 FROM t1; -INSERT INTO t1 SELECT pk1+400, a1, b1 FROM t1; - -ANALYZE TABLE t1,t2 PERSISTENT FOR ALL; - -let $q= -SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 ) - WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); - -eval $q; -eval EXPLAIN EXTENDED $q; -eval EXPLAIN FORMAT=JSON $q; - -DROP TABLE t1,t2; - ---echo # ---echo # MDEV-21794: Optimizer flag rowid_filter leads to long query ---echo # -create table t10(a int); -insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); - -create table t11(a int); -insert into t11 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C; - -CREATE TABLE t1 ( - el_id int(10) unsigned NOT NULL , - el_index blob NOT NULL, - el_index_60 varbinary(60) NOT NULL, - filler blob, - - PRIMARY KEY (el_id), - KEY el_index (el_index(60)), - KEY el_index_60 (el_index_60,el_id) -); - -insert into t1 -select - A.a+1000*B.a, - A.a+1000*B.a + 10000, - A.a+1000*B.a + 10000, - 'filler-data-filler-data' -from - t11 A, t10 B; -analyze table t1 persistent for all; - ---echo # This must not use rowid_filter with key=el_index|el_index_60: -explain -select * from t1 -where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); - -drop table t10, t11, t1; - - ---echo # ---echo # MDEV-22160: SIGSEGV in st_join_table::save_explain_data on SELECT ---echo # - -set @save_optimizer_switch= @@optimizer_switch; -SET @@optimizer_switch="index_merge_sort_union=OFF"; -CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b)); -INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4); -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; - -ANALYZE table t1 PERSISTENT FOR ALL; - -explain -SELECT * FROM t1 WHERE a > 0 AND b=0; -SELECT * FROM t1 WHERE a > 0 AND b=0; -drop table t1; -SET @@optimizer_switch=@save_optimizer_switch; - - ---echo # ---echo # MDEV-28846: Poor performance when rowid filter contains no elements ---echo # - ---source include/have_sequence.inc - -create table t1 ( - pk int primary key auto_increment, - nm varchar(32), - fl1 tinyint default 0, - fl2 tinyint default 0, - index idx1(nm, fl1), - index idx2(fl2) -) engine=myisam; - -create table name ( - pk int primary key auto_increment, - nm bigint -) engine=myisam; - -create table flag2 ( - pk int primary key auto_increment, - fl2 tinyint -) engine=myisam; - -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); - -insert into t1(nm,fl2) - select nm, fl2 from name, flag2 where name.pk = flag2.pk; - -analyze table t1 persistent for all; - -let $a= -`select concat((select nm from t1 where fl2=0 order by RAND(13) limit 1),'%')`; -eval select '$a' as a; - -set optimizer_switch='rowid_filter=on'; -eval -explain -select * from t1 where nm like '$a' AND fl2 = 0; ---source include/analyze-format.inc -eval -analyze format=json -select * from t1 where nm like '$a' AND fl2 = 0; -eval -select * from t1 where nm like '$a' AND fl2 = 0; - -truncate table name; -truncate table flag2; -truncate table t1; - -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); - -insert into t1(nm,fl2) - select nm, fl2 from name, flag2 where name.pk = flag2.pk; - -analyze table t1 persistent for all; - -set optimizer_switch='rowid_filter=off'; -eval -explain -select * from t1 where nm like '$a' AND fl2 = 0; ---source include/analyze-format.inc -eval -analyze format=json -select * from t1 where nm like '$a' AND fl2 = 0; -eval -select * from t1 where nm like '$a' AND fl2 = 0; - -truncate table name; -truncate table flag2; -truncate table t1; - -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 10 from seq_1_to_1000 order by rand(19); - -insert into t1(nm,fl2) - select nm, fl2 from name, flag2 where name.pk = flag2.pk; - -analyze table t1 persistent for all; - -let $a= -`select concat((select nm from t1 where fl2=0 order by RAND(13) limit 1),'%')`; -eval select '$a' as a; - -set optimizer_switch='rowid_filter=on'; -eval -explain -select * from t1 where nm like '$a' AND fl2 = 0; -eval -select * from t1 where nm like '$a' AND fl2 = 0; - -truncate table name; -truncate table flag2; -truncate table t1; - -insert into name(nm) select seq from seq_1_to_10000 order by rand(17); -insert into flag2(fl2) select seq mod 100 from seq_1_to_10000 order by rand(19); - -insert into t1(nm,fl2) - select nm, fl2 from name, flag2 where name.pk = flag2.pk; - -analyze table t1 persistent for all; - -let $a= -`select concat(left((select nm from t1 where fl2=0 order by RAND(13) limit 1),2),'%')`; -eval select '$a' as a; - -set optimizer_switch='rowid_filter=on'; -eval -explain -select * from t1 where nm like '$a' AND fl2 = 0; ---source include/analyze-format.inc -eval -analyze format=json -select * from t1 where nm like '$a' AND fl2 = 0; -eval -select * from t1 where nm like '$a' AND fl2 = 0; - -drop table name, flag2; -drop table t1; - -# This test shows that if the container is empty there are no lookups into it - -create table t1 ( - pk int primary key auto_increment, - nm char(255), - fl1 tinyint default 0, - fl2 int default 0, - index idx1(nm, fl1), - index idx2(fl2) -) engine=myisam; - -create table name ( - pk int primary key auto_increment, - nm bigint -) engine=myisam; - -create table flag2 ( - pk int primary key auto_increment, - fl2 int -) engine=myisam; - -insert into name(nm) select seq from seq_1_to_10000 order by rand(17); -insert into flag2(fl2) select seq mod 10 from seq_1_to_10000 order by rand(19); - -insert into t1(nm,fl2) - select nm, fl2 from name, flag2 where name.pk = flag2.pk; - -analyze table t1 persistent for all; - -let $q= -select * from t1 -where -( - nm like '3400%' or nm like '3402%' or nm like '3403%' or - nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or - nm like '3409%' or - nm like '3411%' or nm like '3412%' or nm like '3413%' or - nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or - nm like '3418%' or nm like '3419%' or - nm like '3421%' or nm like '3422%' or nm like '3423%' or - nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or - nm like '3428%' or nm like '3429%' or - nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or - nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or - nm like '3439%' or - nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or - nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or - nm like '3448%' -) and fl2 = 0; - -eval $q; ---source include/analyze-format.inc -eval analyze format=json $q; - -create table t0 select * from t1 where nm like '34%'; -delete from t1 using t1,t0 where t1.nm=t0.nm; ---source include/analyze-format.inc -eval analyze format=json $q; - -drop table t0; - -set optimizer_switch='rowid_filter=default'; - -drop table name, flag2; -drop table t1; - -set @@use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/main/rowid_filter_aria.result b/mysql-test/main/rowid_filter_aria.result new file mode 100644 index 00000000000..2478e787a6d --- /dev/null +++ b/mysql-test/main/rowid_filter_aria.result @@ -0,0 +1,2349 @@ +SET SESSION DEFAULT_STORAGE_ENGINE='Aria'; +DROP DATABASE IF EXISTS dbt3_s001; +CREATE DATABASE dbt3_s001; +use dbt3_s001; +CREATE INDEX i_l_quantity ON lineitem(l_quantity); +CREATE INDEX i_o_totalprice ON orders(o_totalprice); +set @save_use_stat_tables= @@use_stat_tables; +set @@use_stat_tables=preferably; +ANALYZE TABLE lineitem, orders; +show create table lineitem; +Table Create Table +lineitem CREATE TABLE `lineitem` ( + `l_orderkey` int(11) NOT NULL DEFAULT 0, + `l_partkey` int(11) DEFAULT NULL, + `l_suppkey` int(11) DEFAULT NULL, + `l_linenumber` int(11) NOT NULL DEFAULT 0, + `l_quantity` double DEFAULT NULL, + `l_extendedprice` double DEFAULT NULL, + `l_discount` double DEFAULT NULL, + `l_tax` double DEFAULT NULL, + `l_returnflag` char(1) DEFAULT NULL, + `l_linestatus` char(1) DEFAULT NULL, + `l_shipDATE` date DEFAULT NULL, + `l_commitDATE` date DEFAULT NULL, + `l_receiptDATE` date DEFAULT NULL, + `l_shipinstruct` char(25) DEFAULT NULL, + `l_shipmode` char(10) DEFAULT NULL, + `l_comment` varchar(44) DEFAULT NULL, + PRIMARY KEY (`l_orderkey`,`l_linenumber`), + KEY `i_l_shipdate` (`l_shipDATE`), + KEY `i_l_suppkey_partkey` (`l_partkey`,`l_suppkey`), + KEY `i_l_partkey` (`l_partkey`), + KEY `i_l_suppkey` (`l_suppkey`), + KEY `i_l_receiptdate` (`l_receiptDATE`), + KEY `i_l_orderkey` (`l_orderkey`), + KEY `i_l_orderkey_quantity` (`l_orderkey`,`l_quantity`), + KEY `i_l_commitdate` (`l_commitDATE`), + KEY `i_l_quantity` (`l_quantity`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +show create table orders; +Table Create Table +orders CREATE TABLE `orders` ( + `o_orderkey` int(11) NOT NULL, + `o_custkey` int(11) DEFAULT NULL, + `o_orderstatus` char(1) DEFAULT NULL, + `o_totalprice` double DEFAULT NULL, + `o_orderDATE` date DEFAULT NULL, + `o_orderpriority` char(15) DEFAULT NULL, + `o_clerk` char(15) DEFAULT NULL, + `o_shippriority` int(11) DEFAULT NULL, + `o_comment` varchar(79) DEFAULT NULL, + PRIMARY KEY (`o_orderkey`), + KEY `i_o_orderdate` (`o_orderDATE`), + KEY `i_o_custkey` (`o_custkey`), + KEY `i_o_totalprice` (`o_totalprice`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +set optimizer_use_condition_selectivity=2; +select +100 * +(select count(*) from lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 45 +) +/ +(select count(*) from lineitem +where l_shipdate BETWEEN '1997-01-01' AND '1997-06-30') +as correct_r_filtered_when_using_l_shipdate; +correct_r_filtered_when_using_l_shipdate +11.7647 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter i_l_shipdate,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 482 (16%) Using index condition; Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": ["i_l_shipdate", "i_l_quantity"], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rowid_filter": { + "range": { + "key": "i_l_quantity", + "used_key_parts": ["l_quantity"] + }, + "rows": 949, + "selectivity_pct": 15.80349709 + }, + "loops": 1, + "rows": 482, + "cost": "COST_REPLACED", + "filtered": 15.80349731, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for ANALYZE SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE lineitem range|filter i_l_shipdate,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 482 (16%) 60.00 (11%) 15.80 100.00 Using index condition; Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": ["i_l_shipdate", "i_l_quantity"], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rowid_filter": { + "range": { + "key": "i_l_quantity", + "used_key_parts": ["l_quantity"] + }, + "rows": 949, + "selectivity_pct": 15.80349709, + "r_rows": 605, + "r_lookups": 510, + "r_selectivity_pct": 11.76470588, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 1, + "r_loops": 1, + "rows": 482, + "r_rows": 60, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 15.80349731, + "r_filtered": 100, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +l_orderkey l_linenumber l_shipdate l_quantity +1121 5 1997-04-27 47 +1121 6 1997-04-21 50 +1441 7 1997-06-07 50 +1443 1 1997-02-05 47 +1473 1 1997-05-05 50 +1568 2 1997-04-06 46 +1632 1 1997-01-25 47 +1632 3 1997-01-29 47 +1954 7 1997-06-04 49 +1959 1 1997-05-05 46 +2151 3 1997-01-20 49 +2177 5 1997-05-10 46 +2369 2 1997-01-02 47 +2469 3 1997-01-11 48 +2469 6 1997-03-03 49 +2470 2 1997-06-02 50 +260 1 1997-03-24 50 +288 2 1997-04-19 49 +289 4 1997-03-14 48 +3009 1 1997-03-19 48 +3105 3 1997-02-28 48 +3106 2 1997-02-27 49 +3429 1 1997-04-08 48 +3490 2 1997-06-27 50 +3619 1 1997-01-22 49 +3619 3 1997-01-31 46 +3969 3 1997-05-29 46 +4005 4 1997-01-31 49 +4036 1 1997-06-21 46 +4066 4 1997-02-17 49 +4098 1 1997-01-26 46 +422 3 1997-06-21 46 +4258 3 1997-01-02 46 +4421 2 1997-04-21 46 +4421 3 1997-05-25 46 +4453 3 1997-05-29 48 +4484 7 1997-03-17 50 +4609 3 1997-02-11 46 +484 1 1997-03-06 49 +484 3 1997-01-24 50 +484 5 1997-03-05 48 +485 1 1997-03-28 50 +4868 1 1997-04-29 47 +4868 3 1997-04-23 49 +4934 1 1997-05-20 48 +4967 1 1997-05-27 50 +5090 2 1997-04-05 46 +5152 2 1997-03-10 50 +5158 4 1997-04-10 49 +5606 3 1997-03-11 46 +5606 7 1997-02-01 46 +5762 4 1997-03-02 47 +581 3 1997-02-27 49 +5829 5 1997-01-31 49 +5831 4 1997-02-24 46 +5895 2 1997-04-27 47 +5895 3 1997-03-15 49 +5952 1 1997-06-30 49 +705 1 1997-04-18 46 +836 3 1997-03-21 46 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range i_l_shipdate,i_l_quantity i_l_shipdate 4 NULL 482 Using index condition; Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": ["i_l_shipdate", "i_l_quantity"], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "loops": 1, + "rows": 482, + "cost": "COST_REPLACED", + "filtered": 15.80349731, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for ANALYZE SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE lineitem range i_l_shipdate,i_l_quantity i_l_shipdate 4 NULL 482 510.00 15.80 11.76 Using index condition; Using where +set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": ["i_l_shipdate", "i_l_quantity"], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "loops": 1, + "r_loops": 1, + "rows": 482, + "r_rows": 510, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 15.80349731, + "r_filtered": 11.76470588, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT l_orderkey, l_linenumber, l_shipdate, l_quantity FROM lineitem +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45; +l_orderkey l_linenumber l_shipdate l_quantity +1121 5 1997-04-27 47 +1121 6 1997-04-21 50 +1441 7 1997-06-07 50 +1443 1 1997-02-05 47 +1473 1 1997-05-05 50 +1568 2 1997-04-06 46 +1632 1 1997-01-25 47 +1632 3 1997-01-29 47 +1954 7 1997-06-04 49 +1959 1 1997-05-05 46 +2151 3 1997-01-20 49 +2177 5 1997-05-10 46 +2369 2 1997-01-02 47 +2469 3 1997-01-11 48 +2469 6 1997-03-03 49 +2470 2 1997-06-02 50 +260 1 1997-03-24 50 +288 2 1997-04-19 49 +289 4 1997-03-14 48 +3009 1 1997-03-19 48 +3105 3 1997-02-28 48 +3106 2 1997-02-27 49 +3429 1 1997-04-08 48 +3490 2 1997-06-27 50 +3619 1 1997-01-22 49 +3619 3 1997-01-31 46 +3969 3 1997-05-29 46 +4005 4 1997-01-31 49 +4036 1 1997-06-21 46 +4066 4 1997-02-17 49 +4098 1 1997-01-26 46 +422 3 1997-06-21 46 +4258 3 1997-01-02 46 +4421 2 1997-04-21 46 +4421 3 1997-05-25 46 +4453 3 1997-05-29 48 +4484 7 1997-03-17 50 +4609 3 1997-02-11 46 +484 1 1997-03-06 49 +484 3 1997-01-24 50 +484 5 1997-03-05 48 +485 1 1997-03-28 50 +4868 1 1997-04-29 47 +4868 3 1997-04-23 49 +4934 1 1997-05-20 48 +4967 1 1997-05-27 50 +5090 2 1997-04-05 46 +5152 2 1997-03-10 50 +5158 4 1997-04-10 49 +5606 3 1997-03-11 46 +5606 7 1997-02-01 46 +5762 4 1997-03-02 47 +581 3 1997-02-27 49 +5829 5 1997-01-31 49 +5831 4 1997-02-24 46 +5895 2 1997-04-27 47 +5895 3 1997-03-15 49 +5952 1 1997-06-30 49 +705 1 1997-04-18 46 +836 3 1997-03-21 46 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 92 Using index condition +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (7%) Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "loops": 1, + "rows": 92, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rowid_filter": { + "range": { + "key": "i_o_totalprice", + "used_key_parts": ["o_totalprice"] + }, + "rows": 106, + "selectivity_pct": 7.066666667 + }, + "loops": 92, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 7.066666603, + "attached_condition": "orders.o_totalprice between 200000 and 230000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for ANALYZE SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 92 98.00 100.00 100.00 Using index condition +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (7%) 0.11 (10%) 7.07 100.00 Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "loops": 1, + "r_loops": 1, + "rows": 92, + "r_rows": 98, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rowid_filter": { + "range": { + "key": "i_o_totalprice", + "used_key_parts": ["o_totalprice"] + }, + "rows": 106, + "selectivity_pct": 7.066666667, + "r_rows": 71, + "r_lookups": 96, + "r_selectivity_pct": 10.41666667, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 92, + "r_loops": 98, + "rows": 1, + "r_rows": 0.112244898, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 7.066666603, + "r_filtered": 100, + "attached_condition": "orders.o_totalprice between 200000 and 230000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 6 1997-01-25 222274.54 +484 3 1997-01-24 219920.62 +5606 6 1997-01-11 219959.08 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 92 Using index condition +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "loops": 1, + "rows": 92, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 92, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 7.066666603, + "attached_condition": "orders.o_totalprice between 200000 and 230000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for ANALYZE SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 NULL 92 98.00 100.00 100.00 Using index condition +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 7.07 11.22 Using where +set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "loops": 1, + "r_loops": 1, + "rows": 92, + "r_rows": 98, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 92, + "r_loops": 98, + "rows": 1, + "r_rows": 1, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 7.066666603, + "r_filtered": 11.2244898, + "attached_condition": "orders.o_totalprice between 200000 and 230000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 6 1997-01-25 222274.54 +484 3 1997-01-24 219920.62 +5606 6 1997-01-11 219959.08 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 482 (16%) Using index condition; Using where; Using rowid filter +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (14%) Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity", + "i_l_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rowid_filter": { + "range": { + "key": "i_l_quantity", + "used_key_parts": ["l_quantity"] + }, + "rows": 949, + "selectivity_pct": 15.80349709 + }, + "loops": 1, + "rows": 482, + "cost": "COST_REPLACED", + "filtered": 15.80349731, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rowid_filter": { + "range": { + "key": "i_o_totalprice", + "used_key_parts": ["o_totalprice"] + }, + "rows": 216, + "selectivity_pct": 14.4 + }, + "loops": 76.17285595, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 14.39999962, + "attached_condition": "orders.o_totalprice between 180000 and 230000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for ANALYZE SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE lineitem range|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 482 (16%) 60.00 (11%) 15.80 100.00 Using index condition; Using where; Using rowid filter +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (14%) 0.27 (25%) 14.40 100.00 Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity", + "i_l_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "rowid_filter": { + "range": { + "key": "i_l_quantity", + "used_key_parts": ["l_quantity"] + }, + "rows": 949, + "selectivity_pct": 15.80349709, + "r_rows": 605, + "r_lookups": 510, + "r_selectivity_pct": 11.76470588, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 1, + "r_loops": 1, + "rows": 482, + "r_rows": 60, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 15.80349731, + "r_filtered": 100, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "rowid_filter": { + "range": { + "key": "i_o_totalprice", + "used_key_parts": ["o_totalprice"] + }, + "rows": 216, + "selectivity_pct": 14.4, + "r_rows": 144, + "r_lookups": 59, + "r_selectivity_pct": 25.42372881, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 76.17285595, + "r_loops": 60, + "rows": 1, + "r_rows": 0.266666667, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 14.39999962, + "r_filtered": 100, + "attached_condition": "orders.o_totalprice between 180000 and 230000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +o_orderkey l_linenumber l_shipdate l_quantity o_totalprice +1632 1 1997-01-25 47 183286.33 +1632 3 1997-01-29 47 183286.33 +2177 5 1997-05-10 46 183493.42 +2469 3 1997-01-11 48 192074.23 +2469 6 1997-03-03 49 192074.23 +3619 1 1997-01-22 49 222274.54 +3619 3 1997-01-31 46 222274.54 +484 1 1997-03-06 49 219920.62 +484 3 1997-01-24 50 219920.62 +484 5 1997-03-05 48 219920.62 +4934 1 1997-05-20 48 180478.16 +5606 3 1997-03-11 46 219959.08 +5606 7 1997-02-01 46 219959.08 +5829 5 1997-01-31 49 183734.56 +5895 2 1997-04-27 47 201419.83 +5895 3 1997-03-15 49 201419.83 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate 4 NULL 482 Using index condition; Using where +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity", + "i_l_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "loops": 1, + "rows": 482, + "cost": "COST_REPLACED", + "filtered": 15.80349731, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 76.17285595, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 14.39999962, + "attached_condition": "orders.o_totalprice between 180000 and 230000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for ANALYZE SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate 4 NULL 482 510.00 15.80 11.76 Using index condition; Using where +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 14.40 26.67 Using where +set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity", + "i_l_quantity" + ], + "key": "i_l_shipdate", + "key_length": "4", + "used_key_parts": ["l_shipDATE"], + "loops": 1, + "r_loops": 1, + "rows": 482, + "r_rows": 510, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 15.80349731, + "r_filtered": 11.76470588, + "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", + "attached_condition": "lineitem.l_quantity > 45" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 76.17285595, + "r_loops": 60, + "rows": 1, + "r_rows": 1, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 14.39999962, + "r_filtered": 26.66666667, + "attached_condition": "orders.o_totalprice between 180000 and 230000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +o_orderkey l_linenumber l_shipdate l_quantity o_totalprice +1632 1 1997-01-25 47 183286.33 +1632 3 1997-01-29 47 183286.33 +2177 5 1997-05-10 46 183493.42 +2469 3 1997-01-11 48 192074.23 +2469 6 1997-03-03 49 192074.23 +3619 1 1997-01-22 49 222274.54 +3619 3 1997-01-31 46 222274.54 +484 1 1997-03-06 49 219920.62 +484 3 1997-01-24 50 219920.62 +484 5 1997-03-05 48 219920.62 +4934 1 1997-05-20 48 180478.16 +5606 3 1997-03-11 46 219959.08 +5606 7 1997-02-01 46 219959.08 +5829 5 1997-01-31 49 183734.56 +5895 2 1997-04-27 47 201419.83 +5895 3 1997-03-15 49 201419.83 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT STRAIGHT_JOIN o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM lineitem JOIN orders ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 482 (16%) Using index condition; Using where; Using rowid filter +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_totalprice PRIMARY|i_o_totalprice 4|9 dbt3_s001.lineitem.l_orderkey 1 (14%) Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 106 Using index condition +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (8%) Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "loops": 1, + "rows": 106, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "orders.o_totalprice between 200000 and 230000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_orderkey", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 482, + "selectivity_pct": 8.026644463 + }, + "loops": 106, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 8.026644707, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for ANALYZE SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 106 71.00 100.00 100.00 Using index condition +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (8%) 0.52 (7%) 8.03 100.00 Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "loops": 1, + "r_loops": 1, + "rows": 106, + "r_rows": 71, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100, + "index_condition": "orders.o_totalprice between 200000 and 230000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_orderkey", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 482, + "selectivity_pct": 8.026644463, + "r_rows": 510, + "r_lookups": 476, + "r_selectivity_pct": 7.773109244, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 106, + "r_loops": 71, + "rows": 4, + "r_rows": 0.521126761, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 8.026644707, + "r_filtered": 100, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +1890 1 1997-04-02 202364.58 +1890 3 1997-02-09 202364.58 +1890 4 1997-04-08 202364.58 +1890 5 1997-04-15 202364.58 +1890 6 1997-02-13 202364.58 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 4 1997-03-18 222274.54 +3619 6 1997-01-25 222274.54 +453 1 1997-06-30 216826.73 +453 2 1997-06-30 216826.73 +484 1 1997-03-06 219920.62 +484 2 1997-04-09 219920.62 +484 3 1997-01-24 219920.62 +484 4 1997-04-29 219920.62 +484 5 1997-03-05 219920.62 +484 6 1997-04-06 219920.62 +5606 2 1997-02-23 219959.08 +5606 3 1997-03-11 219959.08 +5606 4 1997-02-06 219959.08 +5606 6 1997-01-11 219959.08 +5606 7 1997-02-01 219959.08 +5859 2 1997-05-15 210643.96 +5859 5 1997-05-28 210643.96 +5859 6 1997-06-15 210643.96 +5895 1 1997-04-05 201419.83 +5895 2 1997-04-27 201419.83 +5895 3 1997-03-15 201419.83 +5895 4 1997-03-03 201419.83 +5895 5 1997-04-30 201419.83 +5895 6 1997-04-19 201419.83 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 106 Using index condition +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "loops": 1, + "rows": 106, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "orders.o_totalprice between 200000 and 230000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_orderkey", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 106, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 8.026644707, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for ANALYZE SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice i_o_totalprice 9 NULL 106 71.00 100.00 100.00 Using index condition +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.70 8.03 7.77 Using where +set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "i_o_totalprice", + "key_length": "9", + "used_key_parts": ["o_totalprice"], + "loops": 1, + "r_loops": 1, + "rows": 106, + "r_rows": 71, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 100, + "index_condition": "orders.o_totalprice between 200000 and 230000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_orderkey", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 106, + "r_loops": 71, + "rows": 4, + "r_rows": 6.704225352, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 8.026644707, + "r_filtered": 7.773109244, + "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice +FROM orders JOIN lineitem ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +o_totalprice between 200000 and 230000; +o_orderkey l_linenumber l_shipdate o_totalprice +1156 3 1997-01-24 217682.81 +1156 4 1997-01-18 217682.81 +1156 6 1997-01-27 217682.81 +1156 7 1997-01-01 217682.81 +1890 1 1997-04-02 202364.58 +1890 3 1997-02-09 202364.58 +1890 4 1997-04-08 202364.58 +1890 5 1997-04-15 202364.58 +1890 6 1997-02-13 202364.58 +2180 2 1997-01-03 208481.57 +2180 3 1997-01-03 208481.57 +3619 1 1997-01-22 222274.54 +3619 3 1997-01-31 222274.54 +3619 4 1997-03-18 222274.54 +3619 6 1997-01-25 222274.54 +453 1 1997-06-30 216826.73 +453 2 1997-06-30 216826.73 +484 1 1997-03-06 219920.62 +484 2 1997-04-09 219920.62 +484 3 1997-01-24 219920.62 +484 4 1997-04-29 219920.62 +484 5 1997-03-05 219920.62 +484 6 1997-04-06 219920.62 +5606 2 1997-02-23 219959.08 +5606 3 1997-03-11 219959.08 +5606 4 1997-02-06 219959.08 +5606 6 1997-01-11 219959.08 +5606 7 1997-02-01 219959.08 +5859 2 1997-05-15 210643.96 +5859 5 1997-05-28 210643.96 +5859 6 1997-06-15 210643.96 +5895 1 1997-04-05 201419.83 +5895 2 1997-04-27 201419.83 +5895 3 1997-03-15 201419.83 +5895 4 1997-03-03 201419.83 +5895 5 1997-04-30 201419.83 +5895 6 1997-04-19 201419.83 +# +# MDEV-18413: find constraint correlated indexes +# +ALTER TABLE lineitem ADD CONSTRAINT l_date CHECK(l_shipdate < l_receiptdate); +# Filter on l_shipdate is not used because it participates in +# the same constraint as l_receiptdate. +# Access is made on l_receiptdate. +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 17 Using index condition; Using where +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_receiptdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_receiptdate", + "key_length": "4", + "used_key_parts": ["l_receiptDATE"], + "loops": 1, + "rows": 17, + "cost": "COST_REPLACED", + "filtered": 0.532889247, + "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 8.466666222, + "attached_condition": "orders.o_totalprice between 200000 and 250000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for ANALYZE SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 17 18.00 0.53 38.89 Using index condition; Using where +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 8.47 14.29 Using where +set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_receiptdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_receiptdate", + "key_length": "4", + "used_key_parts": ["l_receiptDATE"], + "loops": 1, + "r_loops": 1, + "rows": 17, + "r_rows": 18, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 0.532889247, + "r_filtered": 38.88888889, + "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, + "r_loops": 7, + "rows": 1, + "r_rows": 1, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 8.466666222, + "r_filtered": 14.28571429, + "attached_condition": "orders.o_totalprice between 200000 and 250000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +l_shipdate l_receiptdate o_totalprice +1996-10-07 1996-10-08 202623.92 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 17 Using index condition; Using where +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_receiptdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_receiptdate", + "key_length": "4", + "used_key_parts": ["l_receiptDATE"], + "loops": 1, + "rows": 17, + "cost": "COST_REPLACED", + "filtered": 0.532889247, + "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 8.466666222, + "attached_condition": "orders.o_totalprice between 200000 and 250000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for ANALYZE SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 17 18.00 0.53 38.89 Using index condition; Using where +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 8.47 14.29 Using where +set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_receiptdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "i_l_receiptdate", + "key_length": "4", + "used_key_parts": ["l_receiptDATE"], + "loops": 1, + "r_loops": 1, + "rows": 17, + "r_rows": 18, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 0.532889247, + "r_filtered": 38.88888889, + "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" + } + }, + { + "table": { + "table_name": "orders", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "i_o_totalprice"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["o_orderkey"], + "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, + "r_loops": 7, + "rows": 1, + "r_rows": 1, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 8.466666222, + "r_filtered": 14.28571429, + "attached_condition": "orders.o_totalprice between 200000 and 250000" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT l_shipdate, l_receiptdate, o_totalprice +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND +l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND +o_totalprice BETWEEN 200000 AND 250000; +l_shipdate l_receiptdate o_totalprice +1996-10-07 1996-10-08 202623.92 +ALTER TABLE orders ADD COLUMN o_totaldiscount double; +UPDATE orders SET o_totaldiscount = o_totalprice*(o_custkey/1000); +CREATE INDEX i_o_totaldiscount on orders(o_totaldiscount); +ALTER TABLE orders ADD CONSTRAINT o_price CHECK(o_totalprice > o_totaldiscount); +# Filter on o_totalprice is not used because it participates in +# the same constraint as o_discount. +# Access is made on o_discount. +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 61 Using index condition; Using where +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (3%) Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice", "i_o_totaldiscount"], + "key": "i_o_totaldiscount", + "key_length": "9", + "used_key_parts": ["o_totaldiscount"], + "loops": 1, + "rows": 61, + "cost": "COST_REPLACED", + "filtered": 5, + "index_condition": "orders.o_totaldiscount between 18000 and 20000", + "attached_condition": "orders.o_totalprice between 200000 and 220000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 174, + "selectivity_pct": 2.897585346 + }, + "loops": 3.05, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 2.897585392, + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for ANALYZE SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 61 41.00 5.00 2.44 Using index condition; Using where +1 SIMPLE lineitem ref|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY|i_l_shipdate 4|4 dbt3_s001.orders.o_orderkey 4 (3%) 4.00 (66%) 2.90 100.00 Using where; Using rowid filter +set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice", "i_o_totaldiscount"], + "key": "i_o_totaldiscount", + "key_length": "9", + "used_key_parts": ["o_totaldiscount"], + "loops": 1, + "r_loops": 1, + "rows": 61, + "r_rows": 41, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 5, + "r_filtered": 2.43902439, + "index_condition": "orders.o_totaldiscount between 18000 and 20000", + "attached_condition": "orders.o_totalprice between 200000 and 220000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "rowid_filter": { + "range": { + "key": "i_l_shipdate", + "used_key_parts": ["l_shipDATE"] + }, + "rows": 174, + "selectivity_pct": 2.897585346, + "r_rows": 183, + "r_lookups": 6, + "r_selectivity_pct": 66.66666667, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 3.05, + "r_loops": 1, + "rows": 4, + "r_rows": 4, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 2.897585392, + "r_filtered": 100, + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +o_totaldiscount o_totalprice l_shipdate +18016.04288 219707.84 1996-10-02 +18016.04288 219707.84 1996-10-17 +18016.04288 219707.84 1996-11-04 +18016.04288 219707.84 1996-11-14 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 61 Using index condition; Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice", "i_o_totaldiscount"], + "key": "i_o_totaldiscount", + "key_length": "9", + "used_key_parts": ["o_totaldiscount"], + "loops": 1, + "rows": 61, + "cost": "COST_REPLACED", + "filtered": 5, + "index_condition": "orders.o_totaldiscount between 18000 and 20000", + "attached_condition": "orders.o_totalprice between 200000 and 220000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 3.05, + "rows": 4, + "cost": "COST_REPLACED", + "filtered": 2.897585392, + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for ANALYZE SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE orders range PRIMARY,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 61 41.00 5.00 2.44 Using index condition; Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 2.90 66.67 Using where +set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": ["PRIMARY", "i_o_totalprice", "i_o_totaldiscount"], + "key": "i_o_totaldiscount", + "key_length": "9", + "used_key_parts": ["o_totaldiscount"], + "loops": 1, + "r_loops": 1, + "rows": 61, + "r_rows": 41, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 5, + "r_filtered": 2.43902439, + "index_condition": "orders.o_totaldiscount between 18000 and 20000", + "attached_condition": "orders.o_totalprice between 200000 and 220000" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 3.05, + "r_loops": 1, + "rows": 4, + "r_rows": 6, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 2.897585392, + "r_filtered": 66.66666667, + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM orders, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +o_totaldiscount o_totalprice l_shipdate +18016.04288 219707.84 1996-10-02 +18016.04288 219707.84 1996-10-17 +18016.04288 219707.84 1996-11-04 +18016.04288 219707.84 1996-11-14 +CREATE VIEW v1 AS +SELECT * FROM orders +WHERE o_orderdate BETWEEN '1992-12-01' AND '1997-01-01'; +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 61 Using index condition; Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=on' for EXPLAIN FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_o_orderdate", + "i_o_totalprice", + "i_o_totaldiscount" + ], + "key": "i_o_totaldiscount", + "key_length": "9", + "used_key_parts": ["o_totaldiscount"], + "loops": 1, + "rows": 61, + "cost": "REPLACED", + "filtered": "REPLACED", + "index_condition": "orders.o_totaldiscount between 18000 and 20000", + "attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.779166667, + "rows": 4, + "cost": "REPLACED", + "filtered": "REPLACED", + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for ANALYZE SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 61 41.00 # 2.44 Using index condition; Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where +set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_o_orderdate", + "i_o_totalprice", + "i_o_totaldiscount" + ], + "key": "i_o_totaldiscount", + "key_length": "9", + "used_key_parts": ["o_totaldiscount"], + "loops": 1, + "r_loops": 1, + "rows": 61, + "r_rows": 41, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": "REPLACED", + "r_filtered": 2.43902439, + "index_condition": "orders.o_totaldiscount between 18000 and 20000", + "attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.779166667, + "r_loops": 1, + "rows": 4, + "r_rows": 6, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": "REPLACED", + "r_filtered": 66.66666667, + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=on' for SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +o_totaldiscount o_totalprice l_shipdate +18016.04288 219707.84 1996-10-02 +18016.04288 219707.84 1996-10-17 +18016.04288 219707.84 1996-11-04 +18016.04288 219707.84 1996-11-14 +set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 61 Using index condition; Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where +set statement optimizer_switch='rowid_filter=off' for EXPLAIN FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_o_orderdate", + "i_o_totalprice", + "i_o_totaldiscount" + ], + "key": "i_o_totaldiscount", + "key_length": "9", + "used_key_parts": ["o_totaldiscount"], + "loops": 1, + "rows": 61, + "cost": "REPLACED", + "filtered": "REPLACED", + "index_condition": "orders.o_totaldiscount between 18000 and 20000", + "attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.779166667, + "rows": 4, + "cost": "REPLACED", + "filtered": "REPLACED", + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for ANALYZE SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 61 41.00 # 2.44 Using index condition; Using where +1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where +set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "orders", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_o_orderdate", + "i_o_totalprice", + "i_o_totaldiscount" + ], + "key": "i_o_totaldiscount", + "key_length": "9", + "used_key_parts": ["o_totaldiscount"], + "loops": 1, + "r_loops": 1, + "rows": 61, + "r_rows": 41, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": "REPLACED", + "r_filtered": 2.43902439, + "index_condition": "orders.o_totaldiscount between 18000 and 20000", + "attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_l_shipdate", + "i_l_orderkey", + "i_l_orderkey_quantity" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["l_orderkey"], + "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.779166667, + "r_loops": 1, + "rows": 4, + "r_rows": 6, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": "REPLACED", + "r_filtered": 66.66666667, + "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" + } + } + ] + } +} +set statement optimizer_switch='rowid_filter=off' for SELECT o_totaldiscount, o_totalprice, l_shipdate +FROM v1, lineitem +WHERE o_orderkey=l_orderkey AND +o_totaldiscount BETWEEN 18000 AND 20000 AND +o_totalprice BETWEEN 200000 AND 220000 AND +l_shipdate BETWEEN '1996-10-01' AND '1996-12-01'; +o_totaldiscount o_totalprice l_shipdate +18016.04288 219707.84 1996-10-02 +18016.04288 219707.84 1996-10-17 +18016.04288 219707.84 1996-11-04 +18016.04288 219707.84 1996-11-14 +ALTER TABLE lineitem DROP CONSTRAINT l_date; +ALTER TABLE orders DROP CONSTRAINT o_price; +ALTER TABLE orders DROP COLUMN o_totaldiscount; +DROP VIEW v1; +DROP DATABASE dbt3_s001; +use test; diff --git a/mysql-test/main/rowid_filter_aria.test b/mysql-test/main/rowid_filter_aria.test new file mode 100644 index 00000000000..869d398f791 --- /dev/null +++ b/mysql-test/main/rowid_filter_aria.test @@ -0,0 +1,9 @@ +# +# Test rowid filters with Aria +# + +SET SESSION DEFAULT_STORAGE_ENGINE='Aria'; + +#set global aria.optimizer_rowid_compare_cost=0.00001; +#set global aria.optimizer_rowid_copy_cost=0.00001; +--source rowid_filter.test diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index e10ddd6658b..78fc80e6ad7 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -80,6 +80,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -97,7 +98,9 @@ EXPLAIN "rows": 605, "selectivity_pct": 10.07493755 }, + "loops": 1, "rows": 510, + "cost": "COST_REPLACED", "filtered": 10.07493782, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", "attached_condition": "lineitem.l_quantity > 45" @@ -121,6 +124,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -145,9 +149,11 @@ ANALYZE "r_buffer_size": "REPLACED", "r_filling_time_ms": "REPLACED" }, + "loops": 1, "r_loops": 1, "rows": 510, "r_rows": 60, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 10.07493782, @@ -235,6 +241,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -244,7 +251,9 @@ EXPLAIN "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "rows": 510, + "cost": "COST_REPLACED", "filtered": 10.07493782, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", "attached_condition": "lineitem.l_quantity > 45" @@ -268,6 +277,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -279,9 +289,11 @@ ANALYZE "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "r_loops": 1, "rows": 510, "r_rows": 510, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 10.07493782, @@ -372,6 +384,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -386,7 +399,9 @@ EXPLAIN "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "rows": 98, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'", "using_index": true @@ -401,7 +416,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 98, "rows": 1, + "cost": "COST_REPLACED", "filtered": 4.733333111, "attached_condition": "orders.o_totalprice between 200000 and 230000" } @@ -427,6 +444,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -443,9 +461,11 @@ ANALYZE "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "r_loops": 1, "rows": 98, "r_rows": 98, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -463,9 +483,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 98, "r_loops": 98, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 4.733333111, @@ -507,6 +529,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -521,7 +544,9 @@ EXPLAIN "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "rows": 98, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'", "using_index": true @@ -536,7 +561,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 98, "rows": 1, + "cost": "COST_REPLACED", "filtered": 4.733333111, "attached_condition": "orders.o_totalprice between 200000 and 230000" } @@ -562,6 +589,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -578,9 +606,11 @@ ANALYZE "key": "i_l_shipdate", "key_length": "4", "used_key_parts": ["l_shipDATE"], + "loops": 1, "r_loops": 1, "rows": 98, "r_rows": 98, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -598,9 +628,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 98, "r_loops": 98, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 4.733333111, @@ -644,6 +676,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -667,7 +700,9 @@ EXPLAIN "rows": 605, "selectivity_pct": 10.07493755 }, + "loops": 1, "rows": 510, + "cost": "COST_REPLACED", "filtered": 10.07493782, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", "attached_condition": "lineitem.l_quantity > 45" @@ -682,7 +717,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 51.38218152, "rows": 1, + "cost": "COST_REPLACED", "filtered": 9.600000381, "attached_condition": "orders.o_totalprice between 180000 and 230000" } @@ -710,6 +747,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -740,9 +778,11 @@ ANALYZE "r_buffer_size": "REPLACED", "r_filling_time_ms": "REPLACED" }, + "loops": 1, "r_loops": 1, "rows": 510, "r_rows": 60, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 10.07493782, @@ -760,9 +800,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 51.38218152, "r_loops": 60, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 9.600000381, @@ -812,6 +854,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -821,7 +864,9 @@ EXPLAIN "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "rows": 144, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "orders.o_totalprice between 180000 and 230000", "using_index": true @@ -842,7 +887,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 144, "rows": 4, + "cost": "COST_REPLACED", "filtered": 0.855656624, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30' and lineitem.l_quantity > 45" } @@ -870,6 +917,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -881,9 +929,11 @@ ANALYZE "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "r_loops": 1, "rows": 144, "r_rows": 144, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -907,9 +957,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 144, "r_loops": 144, "rows": 4, "r_rows": 6.625, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 0.855656624, @@ -942,6 +994,14 @@ o_orderkey l_linenumber l_shipdate l_quantity o_totalprice 5829 5 1997-01-31 49 183734.56 5895 2 1997-04-27 47 201419.83 5895 3 1997-03-15 49 201419.83 +set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT STRAIGHT_JOIN o_orderkey, l_linenumber, l_shipdate, l_quantity, o_totalprice +FROM lineitem JOIN orders ON o_orderkey=l_orderkey +WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND +l_quantity > 45 AND +o_totalprice between 180000 and 230000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity,i_l_quantity i_l_shipdate|i_l_quantity 4|9 NULL 510 (10%) Using index condition; Using where; Using rowid filter +1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where set statement optimizer_switch='rowid_filter=on' for EXPLAIN SELECT o_orderkey, l_linenumber, l_shipdate, o_totalprice FROM orders JOIN lineitem ON o_orderkey=l_orderkey WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND @@ -957,6 +1017,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -966,7 +1027,9 @@ EXPLAIN "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "rows": 71, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "orders.o_totalprice between 200000 and 230000", "using_index": true @@ -986,7 +1049,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 71, "rows": 4, + "cost": "COST_REPLACED", "filtered": 8.492922783, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" } @@ -1012,6 +1077,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1023,9 +1089,11 @@ ANALYZE "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "r_loops": 1, "rows": 71, "r_rows": 71, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1048,9 +1116,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 71, "r_loops": 71, "rows": 4, "r_rows": 6.704225352, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 8.492922783, @@ -1118,6 +1188,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1127,7 +1198,9 @@ EXPLAIN "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "rows": 71, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "orders.o_totalprice between 200000 and 230000", "using_index": true @@ -1147,7 +1220,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 71, "rows": 4, + "cost": "COST_REPLACED", "filtered": 8.492922783, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" } @@ -1173,6 +1248,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1184,9 +1260,11 @@ ANALYZE "key": "i_o_totalprice", "key_length": "9", "used_key_parts": ["o_totalprice"], + "loops": 1, "r_loops": 1, "rows": 71, "r_rows": 71, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -1209,9 +1287,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 71, "r_loops": 71, "rows": 4, "r_rows": 6.704225352, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 8.492922783, @@ -1290,6 +1370,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1305,7 +1386,9 @@ EXPLAIN "key": "i_l_receiptdate", "key_length": "4", "used_key_parts": ["l_receiptDATE"], + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 0.566194832, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" @@ -1320,7 +1403,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 5.666666508, "attached_condition": "orders.o_totalprice between 200000 and 250000" } @@ -1350,6 +1435,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1367,9 +1453,11 @@ ANALYZE "key": "i_l_receiptdate", "key_length": "4", "used_key_parts": ["l_receiptDATE"], + "loops": 1, "r_loops": 1, "rows": 18, "r_rows": 18, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 0.566194832, @@ -1387,9 +1475,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, "r_loops": 7, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 5.666666508, @@ -1427,6 +1517,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1442,7 +1533,9 @@ EXPLAIN "key": "i_l_receiptdate", "key_length": "4", "used_key_parts": ["l_receiptDATE"], + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 0.566194832, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" @@ -1457,7 +1550,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 5.666666508, "attached_condition": "orders.o_totalprice between 200000 and 250000" } @@ -1487,6 +1582,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1504,9 +1600,11 @@ ANALYZE "key": "i_l_receiptdate", "key_length": "4", "used_key_parts": ["l_receiptDATE"], + "loops": 1, "r_loops": 1, "rows": 18, "r_rows": 18, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 0.566194832, @@ -1524,9 +1622,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["o_orderkey"], "ref": ["dbt3_s001.lineitem.l_orderkey"], + "loops": 1, "r_loops": 7, "rows": 1, "r_rows": 1, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 5.666666508, @@ -1571,6 +1671,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1580,7 +1681,9 @@ EXPLAIN "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "rows": 41, + "cost": "COST_REPLACED", "filtered": 3.333333254, "index_condition": "orders.o_totaldiscount between 18000 and 20000", "attached_condition": "orders.o_totalprice between 200000 and 220000" @@ -1600,7 +1703,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.366666667, "rows": 4, + "cost": "COST_REPLACED", "filtered": 3.047460556, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } @@ -1630,6 +1735,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1641,9 +1747,11 @@ ANALYZE "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "r_loops": 1, "rows": 41, "r_rows": 41, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 3.333333254, @@ -1666,9 +1774,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.366666667, "r_loops": 1, "rows": 4, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 3.047460556, @@ -1709,6 +1819,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -1718,7 +1829,9 @@ EXPLAIN "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "rows": 41, + "cost": "COST_REPLACED", "filtered": 3.333333254, "index_condition": "orders.o_totaldiscount between 18000 and 20000", "attached_condition": "orders.o_totalprice between 200000 and 220000" @@ -1738,7 +1851,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.366666667, "rows": 4, + "cost": "COST_REPLACED", "filtered": 3.047460556, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } @@ -1768,6 +1883,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1779,9 +1895,11 @@ ANALYZE "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "r_loops": 1, "rows": 41, "r_rows": 41, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 3.333333254, @@ -1804,9 +1922,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1.366666667, "r_loops": 1, "rows": 4, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 3.047460556, @@ -1850,6 +1970,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "REPLACED", "nested_loop": [ { "table": { @@ -1864,7 +1985,9 @@ EXPLAIN "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "rows": 41, + "cost": "REPLACED", "filtered": "REPLACED", "index_condition": "orders.o_totaldiscount between 18000 and 20000", "attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'" @@ -1884,7 +2007,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1, "rows": 4, + "cost": "REPLACED", "filtered": "REPLACED", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } @@ -1914,6 +2039,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -1930,9 +2056,11 @@ ANALYZE "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "r_loops": 1, "rows": 41, "r_rows": 41, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": "REPLACED", @@ -1955,9 +2083,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": "REPLACED", @@ -1998,6 +2128,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "REPLACED", "nested_loop": [ { "table": { @@ -2012,7 +2143,9 @@ EXPLAIN "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "rows": 41, + "cost": "REPLACED", "filtered": "REPLACED", "index_condition": "orders.o_totaldiscount between 18000 and 20000", "attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'" @@ -2032,7 +2165,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1, "rows": 4, + "cost": "REPLACED", "filtered": "REPLACED", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" } @@ -2062,6 +2197,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -2078,9 +2214,11 @@ ANALYZE "key": "i_o_totaldiscount", "key_length": "9", "used_key_parts": ["o_totaldiscount"], + "loops": 1, "r_loops": 1, "rows": 41, "r_rows": 41, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": "REPLACED", @@ -2103,9 +2241,11 @@ ANALYZE "key_length": "4", "used_key_parts": ["l_orderkey"], "ref": ["dbt3_s001.orders.o_orderkey"], + "loops": 1, "r_loops": 1, "rows": 4, "r_rows": 6, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": "REPLACED", @@ -2133,703 +2273,6 @@ ALTER TABLE orders DROP COLUMN o_totaldiscount; DROP VIEW v1; DROP DATABASE dbt3_s001; use test; -# -# MDEV-18816: potential range filter for one join table with -# impossible WHERE for another -# -create table t1 ( -pk int not null primary key, c2 varchar(10) , i1 int,key (c2) -) engine=myisam; -insert into t1 values (1,'a',-5),(2,'a',null); -create table t2 ( -pk int, i1 int, c1 varchar(30) , key c1 (c1(30)), key i1 (i1) -) engine=myisam; -insert into t2 values -(1,-5,'a'),(2,null,'a'),(3,null,'a'),(4,null,'a'),(5,5,'a'),(6,null,'a'), -(7,4,'a'),(8,55,'a'),(9,null,'a'),(10,null,'a'),(11,null,'a'),(12,-5,'a'), -(13,-5,'a'),(14,null,'a'),(15,null,'a'),(16,-5,'a'),(17,-5,'a'); -select 1 -from t1 -left join -t2 join t1 as t1_a on t2.i1 = t1_a.pk -on t1.c2 = t2.c1 -where t1_a.pk is null and t1_a.i1 != 3; -1 -explain extended select 1 -from t1 -left join -t2 join t1 as t1_a on t2.i1 = t1_a.pk -on t1.c2 = t2.c1 -where t1_a.pk is null and t1_a.i1 != 3; -id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -Warnings: -Note 1003 select 1 AS `1` from `test`.`t1` join `test`.`t2` join `test`.`t1` `t1_a` where 0 -drop table t1,t2; -# -# MDEV-18640: TABLE::prune_range_rowid_filters: Conditional jump or -# move depends on uninitialized value -# -CREATE TABLE t1 ( -pk INT, i INT, PRIMARY KEY (pk), KEY (pk,i) -) ENGINE=MyISAM; -INSERT INTO t1 VALUES (1,10), (7,70), (2,20); -SELECT * FROM t1 WHERE pk < 5; -pk i -1 10 -2 20 -DROP TABLE t1; -# -# MDEV-18956: Possible rowid filter for subquery for which -# in_to_exists strategy has been chosen -# -CREATE TABLE t1 (pk int) engine=myisam ; -INSERT INTO t1 VALUES (1),(2); -CREATE TABLE t2 ( -pk int auto_increment PRIMARY KEY, -i1 int, i2 int, c2 varchar(1), -KEY (i1), KEY (i2) -) engine=myisam; -INSERT INTO t2 VALUES -(1,8,6,'t'),(2,5,7,'i'),(3,4,4,'h'),(4,207,38,'d'),(5,183,206,'b'), -(6,7,null,'o'),(7,1,2,'j'),(8,17,36,'s'),(9,4,5,'q'),(10,0,6,'l'), -(11,1,9,'j'),(12,5,6,'y'),(13,null,0,'i'),(14,7,7,'x'),(15,5,2,'u'); -SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); -pk -EXPLAIN EXTENDED -SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING -2 SUBQUERY t2 ref i1,i2 i1 5 const 1 100.00 Using index condition; Using where -Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` having 0 -DROP TABLE t1,t2; -# -# MDEV-19255: rowid range filter built for range condition -# that uses in expensive subquery -# -CREATE TABLE t1 ( -pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(a1), KEY(b1) -) ENGINE=MyISAM; -INSERT INTO t1 VALUES -(10,0,'z'),(11,3,'j'),(12,8,'f'),(13,8,'p'),(14,6,'w'),(15,0,'c'),(16,1,'j'), -(17,1,'f'),(18,5,'v'),(19,3,'f'),(20,2,'q'),(21,8,'y'),(22,0,'a'),(23,9,'w'), -(24,3,'e'),(25,1,'b'),(26,9,'r'),(27,2,'k'),(28,5,'c'),(29,3,'k'),(30,9,'b'), -(31,8,'j'),(32,1,'t'),(33,8,'n'),(34,3,'z'),(35,0,'u'),(36,3,'a'),(37,3,'g'), -(38,1,'f'),(39,6,'p'),(40,6,'m'),(41,6,'t'),(42,7,'i'),(43,4,'h'),(44,3,'d'), -(45,2,'b'),(46,1,'o'),(47,2,'j'),(48,6,'s'),(49,5,'q'),(50,6,'l'),(51,9,'j'), -(52,6,'y'),(53,0,'i'),(54,7,'x'),(55,2,'u'),(56,6,'t'),(57,4,'b'),(58,5,'m'), -(59,4,'x'),(60,8,'x'),(61,6,'v'),(62,8,'m'),(63,4,'j'),(64,8,'z'),(65,2,'a'), -(66,9,'i'),(67,4,'g'),(68,8,'h'),(69,1,'p'),(70,8,'a'),(71,0,'x'),(72,2,'s'), -(73,6,'k'),(74,0,'m'),(75,6,'e'),(76,9,'y'),(77,7,'d'),(78,7,'w'),(79,6,'y'), -(80,9,'s'),(81,9,'x'),(82,6,'l'),(83,9,'f'),(84,8,'x'),(85,1,'p'),(86,7,'y'), -(87,6,'p'),(88,1,'g'),(89,3,'c'),(90,5,'h'),(91,3,'p'),(92,2,'b'),(93,1,NULL), -(94,3,NULL),(95,2,'y'),(96,7,'s'),(97,7,'x'),(98,6,'i'),(99,9,'t'),(100,5,'j'), -(101,0,'u'),(102,7,'r'),(103,2,'x'),(104,8,'e'),(105,8,'i'),(106,5,'q'), -(107,8,'z'),(108,3,'k'),(109,65,NULL); -CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 INT, b2 VARCHAR(1)) ENGINE=MyISAM; -INSERT INTO t2 VALUES (1,1,'i'); -INSERT INTO t2 SELECT * FROM t1; -INSERT INTO t1 SELECT pk1+200, a1, b1 FROM t1; -INSERT INTO t1 SELECT pk1+400, a1, b1 FROM t1; -ANALYZE TABLE t1,t2 PERSISTENT FOR ALL; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status OK -test.t2 analyze status Engine-independent statistics collected -test.t2 analyze status OK -SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 ) -WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); -pk1 a1 b1 pk2 a2 b2 -17 1 f 16 1 j -37 3 g 36 3 a -105 8 i 104 8 e -EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 ) -WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 101 100.00 Using where -1 PRIMARY t1 ref a1,b1 a1 5 test.t2.a2 36 28.75 Using where -2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition -Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`pk2` AS `pk2`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a1` = `test`.`t2`.`a2` and `test`.`t1`.`b1` <= (/* select#2 */ select max(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`pk2` <= 1) and `test`.`t1`.`pk1` + 1 = `test`.`t2`.`pk2` + 2 -EXPLAIN FORMAT=JSON SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 ) -WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); -EXPLAIN -{ - "query_block": { - "select_id": 1, - "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "ALL", - "rows": 101, - "filtered": 100, - "attached_condition": "t2.a2 is not null" - } - }, - { - "table": { - "table_name": "t1", - "access_type": "ref", - "possible_keys": ["a1", "b1"], - "key": "a1", - "key_length": "5", - "used_key_parts": ["a1"], - "ref": ["test.t2.a2"], - "rows": 36, - "filtered": 28.75, - "attached_condition": "t1.b1 <= (subquery#2) and t1.pk1 + 1 = t2.pk2 + 2" - } - } - ], - "subqueries": [ - { - "query_block": { - "select_id": 2, - "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "range", - "possible_keys": ["PRIMARY"], - "key": "PRIMARY", - "key_length": "4", - "used_key_parts": ["pk2"], - "rows": 1, - "filtered": 100, - "index_condition": "t2.pk2 <= 1" - } - } - ] - } - } - ] - } -} -DROP TABLE t1,t2; -# -# MDEV-21794: Optimizer flag rowid_filter leads to long query -# -create table t10(a int); -insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -create table t11(a int); -insert into t11 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C; -CREATE TABLE t1 ( -el_id int(10) unsigned NOT NULL , -el_index blob NOT NULL, -el_index_60 varbinary(60) NOT NULL, -filler blob, -PRIMARY KEY (el_id), -KEY el_index (el_index(60)), -KEY el_index_60 (el_index_60,el_id) -); -insert into t1 -select -A.a+1000*B.a, -A.a+1000*B.a + 10000, -A.a+1000*B.a + 10000, -'filler-data-filler-data' -from -t11 A, t10 B; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze Warning Engine-independent statistics are not collected for column 'el_index' -test.t1 analyze Warning Engine-independent statistics are not collected for column 'filler' -test.t1 analyze status OK -# This must not use rowid_filter with key=el_index|el_index_60: -explain -select * from t1 -where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range el_index,el_index_60 el_index 62 NULL 1000 Using where -drop table t10, t11, t1; -# -# MDEV-22160: SIGSEGV in st_join_table::save_explain_data on SELECT -# -set @save_optimizer_switch= @@optimizer_switch; -SET @@optimizer_switch="index_merge_sort_union=OFF"; -CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b)); -INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4); -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -INSERT INTO t1 SELECT * FROM t1; -ANALYZE table t1 PERSISTENT FOR ALL; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status OK -explain -SELECT * FROM t1 WHERE a > 0 AND b=0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range|filter a,b a|b 5|5 NULL 64 (29%) Using index condition; Using where; Using rowid filter -SELECT * FROM t1 WHERE a > 0 AND b=0; -a b -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -drop table t1; -SET @@optimizer_switch=@save_optimizer_switch; -# -# MDEV-28846: Poor performance when rowid filter contains no elements -# -create table t1 ( -pk int primary key auto_increment, -nm varchar(32), -fl1 tinyint default 0, -fl2 tinyint default 0, -index idx1(nm, fl1), -index idx2(fl2) -) engine=myisam; -create table name ( -pk int primary key auto_increment, -nm bigint -) engine=myisam; -create table flag2 ( -pk int primary key auto_increment, -fl2 tinyint -) engine=myisam; -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -select '500%' as a; -a -500% -set optimizer_switch='rowid_filter=on'; -explain -select * from t1 where nm like '500%' AND fl2 = 0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where -analyze format=json -select * from t1 where nm like '500%' AND fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "range", - "possible_keys": ["idx1", "idx2"], - "key": "idx1", - "key_length": "35", - "used_key_parts": ["nm"], - "r_loops": 1, - "rows": 1, - "r_rows": 1, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 49.20000076, - "r_filtered": 100, - "index_condition": "t1.nm like '500%'", - "attached_condition": "t1.fl2 = 0" - } - } - ] - } -} -select * from t1 where nm like '500%' AND fl2 = 0; -pk nm fl1 fl2 -517 500 0 0 -truncate table name; -truncate table flag2; -truncate table t1; -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -set optimizer_switch='rowid_filter=off'; -explain -select * from t1 where nm like '500%' AND fl2 = 0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where -analyze format=json -select * from t1 where nm like '500%' AND fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "range", - "possible_keys": ["idx1", "idx2"], - "key": "idx1", - "key_length": "35", - "used_key_parts": ["nm"], - "r_loops": 1, - "rows": 1, - "r_rows": 1, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 49.20000076, - "r_filtered": 100, - "index_condition": "t1.nm like '500%'", - "attached_condition": "t1.fl2 = 0" - } - } - ] - } -} -select * from t1 where nm like '500%' AND fl2 = 0; -pk nm fl1 fl2 -517 500 0 0 -truncate table name; -truncate table flag2; -truncate table t1; -insert into name(nm) select seq from seq_1_to_1000 order by rand(17); -insert into flag2(fl2) select seq mod 10 from seq_1_to_1000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -select '607%' as a; -a -607% -set optimizer_switch='rowid_filter=on'; -explain -select * from t1 where nm like '607%' AND fl2 = 0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where -select * from t1 where nm like '607%' AND fl2 = 0; -pk nm fl1 fl2 -721 607 0 0 -truncate table name; -truncate table flag2; -truncate table t1; -insert into name(nm) select seq from seq_1_to_10000 order by rand(17); -insert into flag2(fl2) select seq mod 100 from seq_1_to_10000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -select '75%' as a; -a -75% -set optimizer_switch='rowid_filter=on'; -explain -select * from t1 where nm like '75%' AND fl2 = 0; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref|filter idx1,idx2 idx2|idx1 2|35 const 55 (1%) Using where; Using rowid filter -analyze format=json -select * from t1 where nm like '75%' AND fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ref", - "possible_keys": ["idx1", "idx2"], - "key": "idx2", - "key_length": "2", - "used_key_parts": ["fl2"], - "ref": ["const"], - "rowid_filter": { - "range": { - "key": "idx1", - "used_key_parts": ["nm"] - }, - "rows": 115, - "selectivity_pct": 1.15, - "r_rows": 111, - "r_lookups": 100, - "r_selectivity_pct": 2, - "r_buffer_size": "REPLACED", - "r_filling_time_ms": "REPLACED" - }, - "r_loops": 1, - "rows": 55, - "r_rows": 2, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 1.149999976, - "r_filtered": 100, - "attached_condition": "t1.nm like '75%'" - } - } - ] - } -} -select * from t1 where nm like '75%' AND fl2 = 0; -pk nm fl1 fl2 -4543 7503 0 0 -7373 7518 0 0 -drop table name, flag2; -drop table t1; -create table t1 ( -pk int primary key auto_increment, -nm char(255), -fl1 tinyint default 0, -fl2 int default 0, -index idx1(nm, fl1), -index idx2(fl2) -) engine=myisam; -create table name ( -pk int primary key auto_increment, -nm bigint -) engine=myisam; -create table flag2 ( -pk int primary key auto_increment, -fl2 int -) engine=myisam; -insert into name(nm) select seq from seq_1_to_10000 order by rand(17); -insert into flag2(fl2) select seq mod 10 from seq_1_to_10000 order by rand(19); -insert into t1(nm,fl2) -select nm, fl2 from name, flag2 where name.pk = flag2.pk; -analyze table t1 persistent for all; -Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date -select * from t1 -where -( -nm like '3400%' or nm like '3402%' or nm like '3403%' or -nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or -nm like '3409%' or -nm like '3411%' or nm like '3412%' or nm like '3413%' or -nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or -nm like '3418%' or nm like '3419%' or -nm like '3421%' or nm like '3422%' or nm like '3423%' or -nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or -nm like '3428%' or nm like '3429%' or -nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or -nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or -nm like '3439%' or -nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or -nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or -nm like '3448%' -) and fl2 = 0; -pk nm fl1 fl2 -analyze format=json select * from t1 -where -( -nm like '3400%' or nm like '3402%' or nm like '3403%' or -nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or -nm like '3409%' or -nm like '3411%' or nm like '3412%' or nm like '3413%' or -nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or -nm like '3418%' or nm like '3419%' or -nm like '3421%' or nm like '3422%' or nm like '3423%' or -nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or -nm like '3428%' or nm like '3429%' or -nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or -nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or -nm like '3439%' or -nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or -nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or -nm like '3448%' -) and fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ref", - "possible_keys": ["idx1", "idx2"], - "key": "idx2", - "key_length": "5", - "used_key_parts": ["fl2"], - "ref": ["const"], - "rowid_filter": { - "range": { - "key": "idx1", - "used_key_parts": ["nm"] - }, - "rows": 44, - "selectivity_pct": 0.44, - "r_rows": 44, - "r_lookups": 1000, - "r_selectivity_pct": 0, - "r_buffer_size": "REPLACED", - "r_filling_time_ms": "REPLACED" - }, - "r_loops": 1, - "rows": 863, - "r_rows": 0, - "r_table_time_ms": "REPLACED", - "r_other_time_ms": "REPLACED", - "filtered": 0.439999998, - "r_filtered": 100, - "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'" - } - } - ] - } -} -create table t0 select * from t1 where nm like '34%'; -delete from t1 using t1,t0 where t1.nm=t0.nm; -analyze format=json select * from t1 -where -( -nm like '3400%' or nm like '3402%' or nm like '3403%' or -nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or -nm like '3409%' or -nm like '3411%' or nm like '3412%' or nm like '3413%' or -nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or -nm like '3418%' or nm like '3419%' or -nm like '3421%' or nm like '3422%' or nm like '3423%' or -nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or -nm like '3428%' or nm like '3429%' or -nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or -nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or -nm like '3439%' or -nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or -nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or -nm like '3448%' -) and fl2 = 0; -ANALYZE -{ - "query_optimization": { - "r_total_time_ms": "REPLACED" - }, - "query_block": { - "select_id": 1, - "r_loops": 1, - "r_total_time_ms": "REPLACED", - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ref", - "possible_keys": ["idx1", "idx2"], - "key": "idx2", - "key_length": "5", - "used_key_parts": ["fl2"], - "ref": ["const"], - "rowid_filter": { - "range": { - "key": "idx1", - "used_key_parts": ["nm"] - }, - "rows": 44, - "selectivity_pct": 0.44, - "r_rows": 0, - "r_lookups": 0, - "r_selectivity_pct": 0, - "r_buffer_size": "REPLACED", - "r_filling_time_ms": "REPLACED" - }, - "r_loops": 1, - "rows": 853, - "r_rows": 0, - "filtered": 0.439999998, - "r_filtered": 100, - "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'" - } - } - ] - } -} -drop table t0; -set optimizer_switch='rowid_filter=default'; -drop table name, flag2; -drop table t1; -set @@use_stat_tables=@save_use_stat_tables; SET GLOBAL innodb_stats_persistent=@save_stats_persistent; # # MDEV-18755: possible RORI-plan and possible plan with range filter @@ -2888,6 +2331,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2906,7 +2350,9 @@ EXPLAIN "rows": 1, "selectivity_pct": 1.587301587 }, + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 1.587301612, "index_condition": "t1.f1 is null", "attached_condition": "t1.f2 is null and (t1.f2 between 'a' and 'z' or t1.f1 = 'a')" @@ -2919,6 +2365,7 @@ EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -2937,7 +2384,9 @@ EXPLAIN "rows": 1, "selectivity_pct": 1.587301587 }, + "loops": 1, "rows": 1, + "cost": "COST_REPLACED", "filtered": 1.587301612, "index_condition": "t1.f1 is null", "attached_condition": "t1.f2 is null and (t1.f2 between 'a' and 'z' or t1.f1 = 'a')" @@ -2966,8 +2415,8 @@ id y x 1 2 1 explain extended select * from t1 join t2 on t1.id = t2.x where t2.y = 2 and t1.id = 1; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00 Using index -1 SIMPLE t2 index_merge x,y y,x 5,5 NULL 1 100.00 Using intersect(y,x); Using where; Using index +1 SIMPLE t1 const PRIMARY PRIMARY 4 const # # +1 SIMPLE t2 ref|filter x,y y|x 5|5 const # # Using where; Using rowid filter Warnings: Note 1003 select 1 AS `id`,`test`.`t2`.`y` AS `y`,`test`.`t2`.`x` AS `x` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`y` = 2 and `test`.`t2`.`x` = 1 drop table t1, t2; @@ -3004,7 +2453,7 @@ count(*) 5 explain extended select count(*) from t1 where a between 21 and 30 and b=2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ref b,a b 5 const 24 9.60 Using where +1 SIMPLE t1 ref|filter b,a b|a 5|5 const 24 (10%) 9.60 Using where; Using rowid filter Warnings: Note 1003 select count(0) AS `count(*)` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` between 21 and 30 select * from t1 where a between 21 and 30 and b=2; @@ -3041,12 +2490,12 @@ Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK EXPLAIN EXTENDED -SELECT a FROM t1 WHERE c < 'k' AND b > 't' ORDER BY a; +SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range|filter b,c b|c 13|1027 NULL 5 (42%) 41.67 Using index condition; Using where; Using filesort; Using rowid filter +1 SIMPLE t1 range|filter b,c b|c 13|1027 NULL 5 (21%) 20.83 Using index condition; Using where; Using filesort; Using rowid filter Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`c` < 'k' and `test`.`t1`.`b` > 't' order by `test`.`t1`.`a` -SELECT a FROM t1 WHERE c < 'k' AND b > 't' ORDER BY a; +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`c` < 'e' and `test`.`t1`.`b` > 't' order by `test`.`t1`.`a` +SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a; a 1 5 @@ -3513,7 +2962,7 @@ SELECT * FROM t1 WHERE (a BETWEEN 9 AND 10 OR a IS NULL) AND (b BETWEEN 9 AND 10 OR b = 9) ORDER BY pk LIMIT 1; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 index a,b PRIMARY 4 NULL 75 54.55 Using where +1 SIMPLE t1 index a,b PRIMARY 4 NULL 73 56.05 Using where Warnings: Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` between 9 and 10 or `test`.`t1`.`a` is null) and (`test`.`t1`.`b` between 9 and 10 or `test`.`t1`.`b` = 9) order by `test`.`t1`.`pk` limit 1 ANALYZE @@ -3715,7 +3164,7 @@ fi.fh in (6311439873746261694,-397087483897438286, id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t index_merge PRIMARY,acli_rid,acli_tp acli_tp,acli_rid 2,767 NULL 2 100.00 Using intersect(acli_tp,acli_rid); Using where; Using index 1 SIMPLE a ref PRIMARY,acei_aclid acei_aclid 8 test.t.id 1 100.00 Using where -1 SIMPLE fi ref filt_aceid,filt_fh filt_aceid 8 test.a.id 24 14.46 Using where +1 SIMPLE fi ref|filter filt_aceid,filt_fh filt_aceid|filt_fh 8|8 test.a.id 24 (14%) 14.46 Using where; Using rowid filter Warnings: Note 1003 select `test`.`t`.`id` AS `id`,`test`.`fi`.`id` AS `id`,`test`.`fi`.`aceid` AS `aceid`,`test`.`fi`.`clid` AS `clid`,`test`.`fi`.`fh` AS `fh` from `test`.`acli` `t` join `test`.`acei` `a` join `test`.`filt` `fi` where `test`.`t`.`tp` = 121 and `test`.`a`.`atp` = 1 and `test`.`fi`.`aceid` = `test`.`a`.`id` and `test`.`a`.`aclid` = `test`.`t`.`id` and `test`.`t`.`rid` = 'B5FCC8C7111E4E3CBC21AAF5012F59C2' and `test`.`fi`.`fh` in (6311439873746261694,-397087483897438286,8518228073041491534,-5420422472375069774) set statement optimizer_switch='rowid_filter=on' for select t.id, fi.* @@ -3831,7 +3280,7 @@ fi.fh in (6311439873746261694,-397087483897438286, id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t index_merge PRIMARY,acli_rid,acli_tp acli_tp,acli_rid 2,767 NULL 2 100.00 Using intersect(acli_tp,acli_rid); Using where; Using index 1 SIMPLE a ref PRIMARY,acei_aclid acei_aclid 8 test.t.id 1 100.00 Using where; Using join buffer (flat, BKA join); Rowid-ordered scan -1 SIMPLE fi ref filt_aceid,filt_fh filt_aceid 8 test.a.id 24 14.46 Using where; Using join buffer (incremental, BKA join); Rowid-ordered scan +1 SIMPLE fi ref|filter filt_aceid,filt_fh filt_aceid|filt_fh 8|8 test.a.id 24 (14%) 14.46 Using where; Using join buffer (incremental, BKA join); Rowid-ordered scan; Using rowid filter Warnings: Note 1003 select `test`.`t`.`id` AS `id`,`test`.`fi`.`id` AS `id`,`test`.`fi`.`aceid` AS `aceid`,`test`.`fi`.`clid` AS `clid`,`test`.`fi`.`fh` AS `fh` from `test`.`acli` `t` join `test`.`acei` `a` join `test`.`filt` `fi` where `test`.`t`.`tp` = 121 and `test`.`a`.`atp` = 1 and `test`.`fi`.`aceid` = `test`.`a`.`id` and `test`.`a`.`aclid` = `test`.`t`.`id` and `test`.`t`.`rid` = 'B5FCC8C7111E4E3CBC21AAF5012F59C2' and `test`.`fi`.`fh` in (6311439873746261694,-397087483897438286,8518228073041491534,-5420422472375069774) set statement optimizer_switch='rowid_filter=on' for select t.id, fi.* @@ -3892,6 +3341,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -3917,9 +3367,11 @@ ANALYZE } ] }, + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3938,9 +3390,11 @@ ANALYZE "key_length": "8", "used_key_parts": ["aclid"], "ref": ["test.t.id"], + "loops": 2, "r_loops": 1, "rows": 1, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3951,7 +3405,8 @@ ANALYZE "join_type": "BKA", "mrr_type": "Rowid-ordered scan", "attached_condition": "a.atp = 1", - "r_filtered": 100 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } }, { @@ -3964,9 +3419,24 @@ ANALYZE "key_length": "8", "used_key_parts": ["aceid"], "ref": ["test.a.id"], + "rowid_filter": { + "range": { + "key": "filt_fh", + "used_key_parts": ["fh"] + }, + "rows": 81, + "selectivity_pct": 14.46428571, + "r_rows": 80, + "r_lookups": 80, + "r_selectivity_pct": 40, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 3.5384, "r_loops": 1, "rows": 24, - "r_rows": 80, + "r_rows": 32, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 14.46428585, @@ -3977,7 +3447,8 @@ ANALYZE "join_type": "BKA", "mrr_type": "Rowid-ordered scan", "attached_condition": "fi.fh in (6311439873746261694,-397087483897438286,8518228073041491534,-5420422472375069774)", - "r_filtered": 40 + "r_filtered": 100, + "r_unpack_time_ms": "REPLACED" } } ] @@ -4016,6 +3487,16 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK test.t2 analyze status Engine-independent statistics collected test.t2 analyze status OK +EXPLAIN EXTENDED SELECT * FROM t1 +WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1 +WHERE t2.i1 = t1.pk AND t2.i1 BETWEEN 3 AND 5); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 60 100.00 Using where +2 DEPENDENT SUBQUERY t2 ref|filter c1,i1 c1|i1 3|5 func 38 (25%) 25.00 Using where; Full scan on NULL key; Using rowid filter +2 DEPENDENT SUBQUERY a1 ALL NULL NULL NULL NULL 60 100.00 Using join buffer (flat, BNL join) +Warnings: +Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1` AS `c1` from `test`.`t1` where !<`test`.`t1`.`c1`,`test`.`t1`.`pk`>((`test`.`t1`.`c1`,(/* select#2 */ select `test`.`t2`.`c1` from `test`.`t2` join `test`.`t1` `a1` where `test`.`t2`.`i1` = `test`.`t1`.`pk` and `test`.`t2`.`i1` between 3 and 5 and trigcond((`test`.`t1`.`c1`) = `test`.`t2`.`c1`)))) SELECT * FROM t1 WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1 WHERE t2.i1 = t1.pk AND t2.i1 BETWEEN 3 AND 5); @@ -4080,16 +3561,6 @@ pk c1 128 y 129 NULL 133 NULL -EXPLAIN EXTENDED SELECT * FROM t1 -WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1 -WHERE t2.i1 = t1.pk AND t2.i1 BETWEEN 3 AND 5); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 60 100.00 Using where -2 DEPENDENT SUBQUERY t2 ref c1,i1 i1 5 test.t1.pk 20 100.00 Using index condition; Using where -2 DEPENDENT SUBQUERY a1 ALL NULL NULL NULL NULL 60 100.00 Using join buffer (flat, BNL join) -Warnings: -Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1` AS `c1` from `test`.`t1` where !<`test`.`t1`.`c1`,`test`.`t1`.`pk`>((`test`.`t1`.`c1`,(/* select#2 */ select `test`.`t2`.`c1` from `test`.`t2` join `test`.`t1` `a1` where `test`.`t2`.`i1` = `test`.`t1`.`pk` and `test`.`t2`.`i1` between 3 and 5 and trigcond((`test`.`t1`.`c1`) = `test`.`t2`.`c1`)))) DROP TABLE t1,t2; set global innodb_stats_persistent= @stats.save; # End of 10.4 tests diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test index 8705a0c9a12..c81cfc71d28 100644 --- a/mysql-test/main/rowid_filter_innodb.test +++ b/mysql-test/main/rowid_filter_innodb.test @@ -49,6 +49,7 @@ let $q= eval $q; eval explain $q; +--source include/explain-no-costs.inc eval explain format=json $q; drop table t1; @@ -70,6 +71,7 @@ let $q= select * from t1 join t2 on t1.id = t2.x where t2.y = 2 and t1.id = 1; eval $q; +--replace_column 9 # 10 # eval explain extended $q; drop table t1, t2; @@ -132,9 +134,9 @@ INSERT INTO t1 VALUES ANALYZE TABLE t1; EXPLAIN EXTENDED -SELECT a FROM t1 WHERE c < 'k' AND b > 't' ORDER BY a; +SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a; -SELECT a FROM t1 WHERE c < 'k' AND b > 't' ORDER BY a; +SELECT a FROM t1 WHERE c < 'e' AND b > 't' ORDER BY a; DROP TABLE t1; SET GLOBAL innodb_stats_persistent= @stats.save; @@ -643,8 +645,8 @@ SELECT * FROM t1 WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1 WHERE t2.i1 = t1.pk AND t2.i1 BETWEEN 3 AND 5); -eval $q; eval EXPLAIN EXTENDED $q; +eval $q; DROP TABLE t1,t2; diff --git a/mysql-test/main/rowid_filter_innodb_debug.result b/mysql-test/main/rowid_filter_innodb_debug.result index f82b29aa1e6..af800346f75 100644 --- a/mysql-test/main/rowid_filter_innodb_debug.result +++ b/mysql-test/main/rowid_filter_innodb_debug.result @@ -2,8 +2,10 @@ set default_storage_engine=innodb; # # MDEV-22761 KILL QUERY during rowid_filter, crashes # +create table t1(a int); +insert into t1 select seq from seq_1_to_1000; create table t2(a int); -insert into t2 select * from seq_0_to_99; +insert into t2 select seq from seq_1_to_100; CREATE TABLE t3 ( key1 int , key2 int, @@ -11,16 +13,11 @@ filler varchar(255), KEY (key1), KEY (key2) ); +insert into t3 select seq,seq, 'filler-data-filler-data' from seq_1_to_2000; select engine from information_schema.tables where table_schema=database() and table_name='t3'; engine InnoDB -insert into t3 -select -A.seq, -B.seq, -'filler-data-filler-data' -from seq_0_to_99 A, seq_0_to_99 B; analyze table t2,t3; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected @@ -30,14 +27,14 @@ test.t3 analyze status OK explain select * from t2, t3 where -t3.key1=t2.a and t3.key2 in (2,3); +t3.key1=t2.a and t3.key2 in (2,3,4,5,6,7,8,9,10); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 100 Using where -1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 100 (2%) Using where; Using rowid filter +1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 1 (0%) Using where; Using rowid filter set debug_sync='handler_rowid_filter_check SIGNAL at_rowid_filter_check WAIT_FOR go'; select * from t2, t3 where -t3.key1=t2.a and t3.key2 in (2,3); +t3.key1=t2.a and t3.key2 in (2,3,4,5,6,7,8,9,10); connect con1, localhost, root,,; set debug_sync='now WAIT_FOR at_rowid_filter_check'; kill query $target_id; @@ -46,5 +43,5 @@ connection default; disconnect con1; ERROR 70100: Query execution was interrupted set debug_sync='RESET'; -drop table t2,t3; +drop table t1,t2,t3; set default_storage_engine=default; diff --git a/mysql-test/main/rowid_filter_innodb_debug.test b/mysql-test/main/rowid_filter_innodb_debug.test index 60381658eaf..99d32f9616d 100644 --- a/mysql-test/main/rowid_filter_innodb_debug.test +++ b/mysql-test/main/rowid_filter_innodb_debug.test @@ -1,7 +1,9 @@ --source include/have_innodb.inc +--source include/have_sequence.inc --source include/no_valgrind_without_big.inc set default_storage_engine=innodb; --source include/rowid_filter_debug_kill.inc set default_storage_engine=default; + diff --git a/mysql-test/main/rowid_filter_myisam.result b/mysql-test/main/rowid_filter_myisam.result index 927257d2cc7..0a56f87f25f 100644 --- a/mysql-test/main/rowid_filter_myisam.result +++ b/mysql-test/main/rowid_filter_myisam.result @@ -1,3 +1,4 @@ +SET optimizer_switch='rowid_filter=on'; # # MDEV-22553: Assertion `info->lastpos == (~ (my_off_t) 0)' failed in mi_rkey with rowid_filer=on # @@ -19,3 +20,698 @@ ALTER TABLE t1 ENABLE KEYS; SELECT * FROM t1 WHERE ( a BETWEEN 255 AND 270 OR f = 200 ) AND f IN ( 1, 4, 112, 143 ) AND d IN ('Montana', 'South Dakota'); a b c d e f DROP TABLE t1; +use test; +# +# MDEV-18816: potential range filter for one join table with +# impossible WHERE for another +# +create table t1 ( +pk int not null primary key, c2 varchar(10) , i1 int,key (c2) +) engine=myisam; +insert into t1 values (1,'a',-5),(2,'a',null); +create table t2 ( +pk int, i1 int, c1 varchar(30) , key c1 (c1(30)), key i1 (i1) +) engine=myisam; +insert into t2 values +(1,-5,'a'),(2,null,'a'),(3,null,'a'),(4,null,'a'),(5,5,'a'),(6,null,'a'), +(7,4,'a'),(8,55,'a'),(9,null,'a'),(10,null,'a'),(11,null,'a'),(12,-5,'a'), +(13,-5,'a'),(14,null,'a'),(15,null,'a'),(16,-5,'a'),(17,-5,'a'); +select 1 +from t1 +left join +t2 join t1 as t1_a on t2.i1 = t1_a.pk +on t1.c2 = t2.c1 +where t1_a.pk is null and t1_a.i1 != 3; +1 +explain extended select 1 +from t1 +left join +t2 join t1 as t1_a on t2.i1 = t1_a.pk +on t1.c2 = t2.c1 +where t1_a.pk is null and t1_a.i1 != 3; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` join `test`.`t2` join `test`.`t1` `t1_a` where 0 +drop table t1,t2; +# +# MDEV-18640: TABLE::prune_range_rowid_filters: Conditional jump or +# move depends on uninitialized value +# +CREATE TABLE t1 ( +pk INT, i INT, PRIMARY KEY (pk), KEY (pk,i) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,10), (7,70), (2,20); +SELECT * FROM t1 WHERE pk < 5; +pk i +1 10 +2 20 +DROP TABLE t1; +# +# MDEV-18956: Possible rowid filter for subquery for which +# in_to_exists strategy has been chosen +# +CREATE TABLE t1 (pk int) engine=myisam ; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 ( +pk int auto_increment PRIMARY KEY, +i1 int, i2 int, c2 varchar(1), +KEY (i1), KEY (i2) +) engine=myisam; +INSERT INTO t2 VALUES +(1,8,6,'t'),(2,5,7,'i'),(3,4,4,'h'),(4,207,38,'d'),(5,183,206,'b'), +(6,7,null,'o'),(7,1,2,'j'),(8,17,36,'s'),(9,4,5,'q'),(10,0,6,'l'), +(11,1,9,'j'),(12,5,6,'y'),(13,null,0,'i'),(14,7,7,'x'),(15,5,2,'u'); +SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); +pk +EXPLAIN EXTENDED +SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` having 0 +DROP TABLE t1,t2; +# +# MDEV-19255: rowid range filter built for range condition +# that uses in expensive subquery +# +CREATE TABLE t1 ( +pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(b1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES +(10,0,'z'),(11,3,'j'),(12,8,'f'),(13,8,'p'),(14,6,'w'),(15,0,'c'),(16,1,'j'), +(17,1,'f'),(18,5,'v'),(19,3,'f'),(20,2,'q'),(21,8,'y'),(22,0,'a'),(23,9,'w'), +(24,3,'e'),(25,1,'b'),(26,9,'r'),(27,2,'k'),(28,5,'c'),(29,3,'k'),(30,9,'b'), +(31,8,'j'),(32,1,'t'),(33,8,'n'),(34,3,'z'),(35,0,'u'),(36,3,'a'),(37,3,'g'), +(38,1,'f'),(39,6,'p'),(40,6,'m'),(41,6,'t'),(42,7,'i'),(43,4,'h'),(44,3,'d'), +(45,2,'b'),(46,1,'o'),(47,2,'j'),(48,6,'s'),(49,5,'q'),(50,6,'l'),(51,9,'j'), +(52,6,'y'),(53,0,'i'),(54,7,'x'),(55,2,'u'),(56,6,'t'),(57,4,'b'),(58,5,'m'), +(59,4,'x'),(60,8,'x'),(61,6,'v'),(62,8,'m'),(63,4,'j'),(64,8,'z'),(65,2,'a'), +(66,9,'i'),(67,4,'g'),(68,8,'h'),(69,1,'p'),(70,8,'a'),(71,0,'x'),(72,2,'s'), +(73,6,'k'),(74,0,'m'),(75,6,'e'),(76,9,'y'),(77,7,'d'),(78,7,'w'),(79,6,'y'), +(80,9,'s'),(81,9,'x'),(82,6,'l'),(83,9,'f'),(84,8,'x'),(85,1,'p'),(86,7,'y'), +(87,6,'p'),(88,1,'g'),(89,3,'c'),(90,5,'h'),(91,3,'p'),(92,2,'b'),(93,1,NULL), +(94,3,NULL),(95,2,'y'),(96,7,'s'),(97,7,'x'),(98,6,'i'),(99,9,'t'),(100,5,'j'), +(101,0,'u'),(102,7,'r'),(103,2,'x'),(104,8,'e'),(105,8,'i'),(106,5,'q'), +(107,8,'z'),(108,3,'k'),(109,65,NULL); +CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 INT, b2 VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,1,'x'); +INSERT INTO t2 SELECT * FROM t1; +SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 ) +WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); +pk1 a1 b1 pk2 a2 b2 +65 2 a 109 65 NULL +EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 ) +WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 101 100.00 Using where +1 PRIMARY t1 eq_ref|filter PRIMARY,b1 PRIMARY|b1 4|4 test.t2.a2 1 (87%) 87.00 Using where; Using rowid filter +2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`pk2` AS `pk2`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`pk1` = `test`.`t2`.`a2` and `test`.`t1`.`b1` <= (/* select#2 */ select max(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`pk2` <= 1) and `test`.`t2`.`a2` <> `test`.`t2`.`pk2` +EXPLAIN FORMAT=JSON SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 ) +WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "ALL", + "loops": 1, + "rows": 101, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t2.a2 <> t2.pk2 and t2.a2 is not null" + } + }, + { + "table": { + "table_name": "t1", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY", "b1"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["pk1"], + "ref": ["test.t2.a2"], + "rowid_filter": { + "range": { + "key": "b1", + "used_key_parts": ["b1"] + }, + "rows": 87, + "selectivity_pct": 87 + }, + "loops": 101, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 87, + "attached_condition": "t1.b1 <= (subquery#2)" + } + } + ], + "subqueries": [ + { + "query_block": { + "select_id": 2, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["pk2"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "index_condition": "t2.pk2 <= 1" + } + } + ] + } + } + ] + } +} +DROP TABLE t1,t2; +# +# MDEV-21794: Optimizer flag rowid_filter leads to long query +# +create table t10(a int); +insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t11(a int); +insert into t11 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C; +CREATE TABLE t1 ( +el_id int(10) unsigned NOT NULL , +el_index blob NOT NULL, +el_index_60 varbinary(60) NOT NULL, +filler blob, +PRIMARY KEY (el_id), +KEY el_index (el_index(60)), +KEY el_index_60 (el_index_60,el_id) +); +insert into t1 +select +A.a+1000*B.a, +A.a+1000*B.a + 10000, +A.a+1000*B.a + 10000, +'filler-data-filler-data' +from +t11 A, t10 B; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 'el_index' +test.t1 analyze Warning Engine-independent statistics are not collected for column 'filler' +test.t1 analyze status Table is already up to date +# This must not use rowid_filter with key=el_index|el_index_60: +explain +select * from t1 +where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range el_index,el_index_60 el_index 62 NULL 645 Using where +drop table t10, t11, t1; +# +# MDEV-22160: SIGSEGV in st_join_table::save_explain_data on SELECT +# +set @save_optimizer_switch= @@optimizer_switch; +SET @@optimizer_switch="index_merge_sort_union=OFF"; +CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b)); +INSERT INTO t1 VALUES (0,0),(0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4),(3,3),(3,4),(3,5),(8,8),(8,9),(1,0),(2,0),(0,0),(0,0); +explain +SELECT * FROM t1 WHERE a > 0 AND b=0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref|filter a,b b|a 5|5 const 7 (47%) Using where; Using rowid filter +SELECT * FROM t1 WHERE a > 0 AND b=0; +a b +1 0 +1 0 +2 0 +drop table t1; +SET @@optimizer_switch=@save_optimizer_switch; +# +# MDEV-21633 +# Assertion `tmp >= 0' failed in best_access_path with rowid_filter=ON +# +set @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='rowid_filter=on'; +CREATE TABLE t1 ( +pk INT AUTO_INCREMENT, +a INT, +b VARCHAR(8), +KEY(a), +PRIMARY KEY(pk), +KEY (a,pk) +) ENGINE=MyISAM; +INSERT INTO t1 (a,b) VALUES +(NULL,'d'),(9,'b'),(2,'x'),(5,'k'),(NULL,'d'),(3,'s'),(5,'k'),(1,'r'), +(8,'l'),(3,'z'),(1,'c'),(1,'q'),(NULL,'x'),(NULL,'p'),(NULL,'z'),(7,'a'), +(0,'i'),(3,'s'),(NULL,'h'),(4,'p'),(1,'i'),(4,'f'),(1,'c'),(NULL,'a'), +(NULL,'x'),(1,'b'),(NULL,'n'),(NULL,'h'),(5,'i'),(6,'e'),(NULL,'i'), +(7,'e'),(1,'r'),(NULL,'z'),(1,'i'),(14,'c'),(6,'u'),(3,'b'),(4,'z'), +(2,'c'),(70,'d'),(NULL,'p'),(21,'j'),(6,'e'),(5,'c'),(13,'i'),(42,'d'), +(80,'s'),(14,'t'),(9,'a'),(0,'2'),(0,NULL),(0,NULL),(0,NULL),(0,''), +(0,''),(0,'1'),(0,''),(0,''),(0,''),(0,''),(0,NULL),(0,''),(0,''),(0,''), +(0,NULL),(0,''),(0,''),(0,''),(0,''),(0,''),(0,''),(0,NULL),(0,NULL), +(0,NULL),(0,''),(0,''),(0,''),(0,''),(0,NULL),(0,''),(0,NULL),(0,NULL), +(0,''),(0,''),(0,''),(0,NULL),(0,''),(0,NULL),(0,''),(0,''),(0,''),(0,''), +(0,''),(0,''),(0,''),(0,NULL),(0,''),(0,NULL),(0,''); +CREATE TABLE t2 (c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6); +SELECT * FROM t1 JOIN t2 WHERE a = c AND pk BETWEEN 4 AND 7 AND a BETWEEN 2 AND 12 AND b != 'foo'; +pk a b c +6 3 s 3 +4 5 k 5 +7 5 k 5 +explain SELECT * FROM t1 JOIN t2 WHERE a = c AND pk BETWEEN 4 AND 7 AND a BETWEEN 2 AND 12 AND b != 'foo'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range|filter PRIMARY,a,a_2 PRIMARY|a 4|5 NULL 4 (11%) Using index condition; Using where; Using rowid filter +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +SET optimizer_switch='rowid_filter=off'; +SELECT * FROM t1 JOIN t2 WHERE a = c AND pk BETWEEN 4 AND 7 AND a BETWEEN 2 AND 12 AND b != 'foo'; +pk a b c +6 3 s 3 +4 5 k 5 +7 5 k 5 +SET @@optimizer_switch=@save_optimizer_switch; +DROP TABLE t1, t2; +# +# MDEV-28846: Poor performance when rowid filter contains no elements +# +create table t1 ( +pk int primary key auto_increment, +nm varchar(32), +fl1 tinyint default 0, +fl2 tinyint default 0, +index idx1(nm, fl1), +index idx2(fl2) +) engine=myisam; +create table name ( +pk int primary key auto_increment, +nm bigint +) engine=myisam; +create table flag2 ( +pk int primary key auto_increment, +fl2 tinyint +) engine=myisam; +insert into name(nm) select seq from seq_1_to_1000 order by rand(17); +insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); +insert into t1(nm,fl2) +select nm, fl2 from name, flag2 where name.pk = flag2.pk; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +select '500%' as a; +a +500% +set optimizer_switch='rowid_filter=on'; +explain +select * from t1 where nm like '500%' AND fl2 = 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where +analyze format=json +select * from t1 where nm like '500%' AND fl2 = 0; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["idx1", "idx2"], + "key": "idx1", + "key_length": "35", + "used_key_parts": ["nm"], + "loops": 1, + "r_loops": 1, + "rows": 1, + "r_rows": 1, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 49.20000076, + "r_filtered": 100, + "index_condition": "t1.nm like '500%'", + "attached_condition": "t1.fl2 = 0" + } + } + ] + } +} +select * from t1 where nm like '500%' AND fl2 = 0; +pk nm fl1 fl2 +517 500 0 0 +truncate table name; +truncate table flag2; +truncate table t1; +insert into name(nm) select seq from seq_1_to_1000 order by rand(17); +insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); +insert into t1(nm,fl2) +select nm, fl2 from name, flag2 where name.pk = flag2.pk; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +set optimizer_switch='rowid_filter=off'; +explain +select * from t1 where nm like '500%' AND fl2 = 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where +analyze format=json +select * from t1 where nm like '500%' AND fl2 = 0; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["idx1", "idx2"], + "key": "idx1", + "key_length": "35", + "used_key_parts": ["nm"], + "loops": 1, + "r_loops": 1, + "rows": 1, + "r_rows": 1, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 49.20000076, + "r_filtered": 100, + "index_condition": "t1.nm like '500%'", + "attached_condition": "t1.fl2 = 0" + } + } + ] + } +} +select * from t1 where nm like '500%' AND fl2 = 0; +pk nm fl1 fl2 +517 500 0 0 +truncate table name; +truncate table flag2; +truncate table t1; +insert into name(nm) select seq from seq_1_to_1000 order by rand(17); +insert into flag2(fl2) select seq mod 10 from seq_1_to_1000 order by rand(19); +insert into t1(nm,fl2) +select nm, fl2 from name, flag2 where name.pk = flag2.pk; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +select '607%' as a; +a +607% +set optimizer_switch='rowid_filter=on'; +explain +select * from t1 where nm like '607%' AND fl2 = 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where +select * from t1 where nm like '607%' AND fl2 = 0; +pk nm fl1 fl2 +721 607 0 0 +truncate table name; +truncate table flag2; +truncate table t1; +insert into name(nm) select seq from seq_1_to_10000 order by rand(17); +insert into flag2(fl2) select seq mod 100 from seq_1_to_10000 order by rand(19); +insert into t1(nm,fl2) +select nm, fl2 from name, flag2 where name.pk = flag2.pk; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +select '75%' as a; +a +75% +set optimizer_switch='rowid_filter=on'; +explain +select * from t1 where nm like '75%' AND fl2 = 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref|filter idx1,idx2 idx2|idx1 2|35 const 55 (1%) Using where; Using rowid filter +analyze format=json +select * from t1 where nm like '75%' AND fl2 = 0; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["idx1", "idx2"], + "key": "idx2", + "key_length": "2", + "used_key_parts": ["fl2"], + "ref": ["const"], + "rowid_filter": { + "range": { + "key": "idx1", + "used_key_parts": ["nm"] + }, + "rows": 115, + "selectivity_pct": 1.15, + "r_rows": 111, + "r_lookups": 100, + "r_selectivity_pct": 2, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 1, + "r_loops": 1, + "rows": 55, + "r_rows": 2, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 1.149999976, + "r_filtered": 100, + "attached_condition": "t1.nm like '75%'" + } + } + ] + } +} +select * from t1 where nm like '75%' AND fl2 = 0; +pk nm fl1 fl2 +4543 7503 0 0 +7373 7518 0 0 +drop table name, flag2; +drop table t1; +create table t1 ( +pk int primary key auto_increment, +nm char(255), +fl1 tinyint default 0, +fl2 int default 0, +index idx1(nm, fl1), +index idx2(fl2) +) engine=myisam; +create table name ( +pk int primary key auto_increment, +nm bigint +) engine=myisam; +create table flag2 ( +pk int primary key auto_increment, +fl2 int +) engine=myisam; +insert into name(nm) select seq from seq_1_to_10000 order by rand(17); +insert into flag2(fl2) select seq mod 10 from seq_1_to_10000 order by rand(19); +insert into t1(nm,fl2) +select nm, fl2 from name, flag2 where name.pk = flag2.pk; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +select * from t1 +where +( +nm like '3400%' or nm like '3402%' or nm like '3403%' or +nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or +nm like '3409%' or +nm like '3411%' or nm like '3412%' or nm like '3413%' or +nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or +nm like '3418%' or nm like '3419%' or +nm like '3421%' or nm like '3422%' or nm like '3423%' or +nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or +nm like '3428%' or nm like '3429%' or +nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or +nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or +nm like '3439%' or +nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or +nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or +nm like '3448%' +) and fl2 = 0; +pk nm fl1 fl2 +analyze format=json select * from t1 +where +( +nm like '3400%' or nm like '3402%' or nm like '3403%' or +nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or +nm like '3409%' or +nm like '3411%' or nm like '3412%' or nm like '3413%' or +nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or +nm like '3418%' or nm like '3419%' or +nm like '3421%' or nm like '3422%' or nm like '3423%' or +nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or +nm like '3428%' or nm like '3429%' or +nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or +nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or +nm like '3439%' or +nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or +nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or +nm like '3448%' +) and fl2 = 0; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["idx1", "idx2"], + "key": "idx1", + "key_length": "256", + "used_key_parts": ["nm"], + "rowid_filter": { + "range": { + "key": "idx2", + "used_key_parts": ["fl2"] + }, + "rows": 863, + "selectivity_pct": 8.63, + "r_rows": 1000, + "r_lookups": 44, + "r_selectivity_pct": 0, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 1, + "r_loops": 1, + "rows": 44, + "r_rows": 0, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 8.630000114, + "r_filtered": 100, + "index_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'", + "attached_condition": "t1.fl2 = 0" + } + } + ] + } +} +create table t0 select * from t1 where nm like '34%'; +delete from t1 using t1,t0 where t1.nm=t0.nm; +analyze format=json select * from t1 +where +( +nm like '3400%' or nm like '3402%' or nm like '3403%' or +nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or +nm like '3409%' or +nm like '3411%' or nm like '3412%' or nm like '3413%' or +nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or +nm like '3418%' or nm like '3419%' or +nm like '3421%' or nm like '3422%' or nm like '3423%' or +nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or +nm like '3428%' or nm like '3429%' or +nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or +nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or +nm like '3439%' or +nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or +nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or +nm like '3448%' +) and fl2 = 0; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "cost": "REPLACED", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["idx1", "idx2"], + "key": "idx1", + "key_length": "256", + "used_key_parts": ["nm"], + "rowid_filter": { + "range": { + "key": "idx2", + "used_key_parts": ["fl2"] + }, + "rows": 853, + "selectivity_pct": 8.53, + "r_rows": 987, + "r_lookups": 0, + "r_selectivity_pct": 0, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "loops": 1, + "r_loops": 1, + "rows": 44, + "r_rows": 0, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "filtered": 8.529999733, + "r_filtered": 100, + "index_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'", + "attached_condition": "t1.fl2 = 0" + } + } + ] + } +} +drop table t0; +set optimizer_switch='rowid_filter=default'; +drop table name, flag2; +drop table t1; diff --git a/mysql-test/main/rowid_filter_myisam.test b/mysql-test/main/rowid_filter_myisam.test index 3ea4dc26ea0..e6eeed83bac 100644 --- a/mysql-test/main/rowid_filter_myisam.test +++ b/mysql-test/main/rowid_filter_myisam.test @@ -1,3 +1,5 @@ +SET optimizer_switch='rowid_filter=on'; + --echo # --echo # MDEV-22553: Assertion `info->lastpos == (~ (my_off_t) 0)' failed in mi_rkey with rowid_filer=on --echo # @@ -1623,3 +1625,406 @@ ALTER TABLE t1 ENABLE KEYS; --echo # Must not crash: SELECT * FROM t1 WHERE ( a BETWEEN 255 AND 270 OR f = 200 ) AND f IN ( 1, 4, 112, 143 ) AND d IN ('Montana', 'South Dakota'); DROP TABLE t1; + + + +use test; + +--echo # +--echo # MDEV-18816: potential range filter for one join table with +--echo # impossible WHERE for another +--echo # + +create table t1 ( + pk int not null primary key, c2 varchar(10) , i1 int,key (c2) +) engine=myisam; +insert into t1 values (1,'a',-5),(2,'a',null); + +create table t2 ( + pk int, i1 int, c1 varchar(30) , key c1 (c1(30)), key i1 (i1) +) engine=myisam; +insert into t2 values + (1,-5,'a'),(2,null,'a'),(3,null,'a'),(4,null,'a'),(5,5,'a'),(6,null,'a'), + (7,4,'a'),(8,55,'a'),(9,null,'a'),(10,null,'a'),(11,null,'a'),(12,-5,'a'), + (13,-5,'a'),(14,null,'a'),(15,null,'a'),(16,-5,'a'),(17,-5,'a'); + +let $q= +select 1 + from t1 + left join + t2 join t1 as t1_a on t2.i1 = t1_a.pk + on t1.c2 = t2.c1 +where t1_a.pk is null and t1_a.i1 != 3; + +eval $q; +eval explain extended $q; + +drop table t1,t2; + +--echo # +--echo # MDEV-18640: TABLE::prune_range_rowid_filters: Conditional jump or +--echo # move depends on uninitialized value +--echo # + +CREATE TABLE t1 ( + pk INT, i INT, PRIMARY KEY (pk), KEY (pk,i) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,10), (7,70), (2,20); + +SELECT * FROM t1 WHERE pk < 5; + +DROP TABLE t1; + +--echo # +--echo # MDEV-18956: Possible rowid filter for subquery for which +--echo # in_to_exists strategy has been chosen +--echo # + +CREATE TABLE t1 (pk int) engine=myisam ; +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 ( + pk int auto_increment PRIMARY KEY, + i1 int, i2 int, c2 varchar(1), + KEY (i1), KEY (i2) +) engine=myisam; + +INSERT INTO t2 VALUES + (1,8,6,'t'),(2,5,7,'i'),(3,4,4,'h'),(4,207,38,'d'),(5,183,206,'b'), + (6,7,null,'o'),(7,1,2,'j'),(8,17,36,'s'),(9,4,5,'q'),(10,0,6,'l'), + (11,1,9,'j'),(12,5,6,'y'),(13,null,0,'i'),(14,7,7,'x'),(15,5,2,'u'); + +SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); +EXPLAIN EXTENDED +SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3); + +DROP TABLE t1,t2; + +--echo # +--echo # MDEV-19255: rowid range filter built for range condition +--echo # that uses in expensive subquery +--echo # + +CREATE TABLE t1 ( + pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(b1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES +(10,0,'z'),(11,3,'j'),(12,8,'f'),(13,8,'p'),(14,6,'w'),(15,0,'c'),(16,1,'j'), +(17,1,'f'),(18,5,'v'),(19,3,'f'),(20,2,'q'),(21,8,'y'),(22,0,'a'),(23,9,'w'), +(24,3,'e'),(25,1,'b'),(26,9,'r'),(27,2,'k'),(28,5,'c'),(29,3,'k'),(30,9,'b'), +(31,8,'j'),(32,1,'t'),(33,8,'n'),(34,3,'z'),(35,0,'u'),(36,3,'a'),(37,3,'g'), +(38,1,'f'),(39,6,'p'),(40,6,'m'),(41,6,'t'),(42,7,'i'),(43,4,'h'),(44,3,'d'), +(45,2,'b'),(46,1,'o'),(47,2,'j'),(48,6,'s'),(49,5,'q'),(50,6,'l'),(51,9,'j'), +(52,6,'y'),(53,0,'i'),(54,7,'x'),(55,2,'u'),(56,6,'t'),(57,4,'b'),(58,5,'m'), +(59,4,'x'),(60,8,'x'),(61,6,'v'),(62,8,'m'),(63,4,'j'),(64,8,'z'),(65,2,'a'), +(66,9,'i'),(67,4,'g'),(68,8,'h'),(69,1,'p'),(70,8,'a'),(71,0,'x'),(72,2,'s'), +(73,6,'k'),(74,0,'m'),(75,6,'e'),(76,9,'y'),(77,7,'d'),(78,7,'w'),(79,6,'y'), +(80,9,'s'),(81,9,'x'),(82,6,'l'),(83,9,'f'),(84,8,'x'),(85,1,'p'),(86,7,'y'), +(87,6,'p'),(88,1,'g'),(89,3,'c'),(90,5,'h'),(91,3,'p'),(92,2,'b'),(93,1,NULL), +(94,3,NULL),(95,2,'y'),(96,7,'s'),(97,7,'x'),(98,6,'i'),(99,9,'t'),(100,5,'j'), +(101,0,'u'),(102,7,'r'),(103,2,'x'),(104,8,'e'),(105,8,'i'),(106,5,'q'), +(107,8,'z'),(108,3,'k'),(109,65,NULL); + +CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 INT, b2 VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,1,'x'); +INSERT INTO t2 SELECT * FROM t1; + +let $q= +SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 ) + WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 ); + +eval $q; +eval EXPLAIN EXTENDED $q; +--source include/explain-no-costs.inc +eval EXPLAIN FORMAT=JSON $q; + +DROP TABLE t1,t2; + +--echo # +--echo # MDEV-21794: Optimizer flag rowid_filter leads to long query +--echo # +create table t10(a int); +insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t11(a int); +insert into t11 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C; + +CREATE TABLE t1 ( + el_id int(10) unsigned NOT NULL , + el_index blob NOT NULL, + el_index_60 varbinary(60) NOT NULL, + filler blob, + + PRIMARY KEY (el_id), + KEY el_index (el_index(60)), + KEY el_index_60 (el_index_60,el_id) +); + +insert into t1 +select + A.a+1000*B.a, + A.a+1000*B.a + 10000, + A.a+1000*B.a + 10000, + 'filler-data-filler-data' +from + t11 A, t10 B; +analyze table t1 persistent for all; + +--echo # This must not use rowid_filter with key=el_index|el_index_60: +explain +select * from t1 +where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); + +drop table t10, t11, t1; + + +--echo # +--echo # MDEV-22160: SIGSEGV in st_join_table::save_explain_data on SELECT +--echo # + +set @save_optimizer_switch= @@optimizer_switch; +SET @@optimizer_switch="index_merge_sort_union=OFF"; +CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b)); +INSERT INTO t1 VALUES (0,0),(0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4),(3,3),(3,4),(3,5),(8,8),(8,9),(1,0),(2,0),(0,0),(0,0); +explain +SELECT * FROM t1 WHERE a > 0 AND b=0; +SELECT * FROM t1 WHERE a > 0 AND b=0; +drop table t1; +SET @@optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # MDEV-21633 +--echo # Assertion `tmp >= 0' failed in best_access_path with rowid_filter=ON +--echo # + +set @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='rowid_filter=on'; + +CREATE TABLE t1 ( + pk INT AUTO_INCREMENT, + a INT, + b VARCHAR(8), + KEY(a), + PRIMARY KEY(pk), + KEY (a,pk) +) ENGINE=MyISAM; + +INSERT INTO t1 (a,b) VALUES + (NULL,'d'),(9,'b'),(2,'x'),(5,'k'),(NULL,'d'),(3,'s'),(5,'k'),(1,'r'), + (8,'l'),(3,'z'),(1,'c'),(1,'q'),(NULL,'x'),(NULL,'p'),(NULL,'z'),(7,'a'), + (0,'i'),(3,'s'),(NULL,'h'),(4,'p'),(1,'i'),(4,'f'),(1,'c'),(NULL,'a'), + (NULL,'x'),(1,'b'),(NULL,'n'),(NULL,'h'),(5,'i'),(6,'e'),(NULL,'i'), + (7,'e'),(1,'r'),(NULL,'z'),(1,'i'),(14,'c'),(6,'u'),(3,'b'),(4,'z'), + (2,'c'),(70,'d'),(NULL,'p'),(21,'j'),(6,'e'),(5,'c'),(13,'i'),(42,'d'), + (80,'s'),(14,'t'),(9,'a'),(0,'2'),(0,NULL),(0,NULL),(0,NULL),(0,''), + (0,''),(0,'1'),(0,''),(0,''),(0,''),(0,''),(0,NULL),(0,''),(0,''),(0,''), + (0,NULL),(0,''),(0,''),(0,''),(0,''),(0,''),(0,''),(0,NULL),(0,NULL), + (0,NULL),(0,''),(0,''),(0,''),(0,''),(0,NULL),(0,''),(0,NULL),(0,NULL), + (0,''),(0,''),(0,''),(0,NULL),(0,''),(0,NULL),(0,''),(0,''),(0,''),(0,''), + (0,''),(0,''),(0,''),(0,NULL),(0,''),(0,NULL),(0,''); + +CREATE TABLE t2 (c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6); + +SELECT * FROM t1 JOIN t2 WHERE a = c AND pk BETWEEN 4 AND 7 AND a BETWEEN 2 AND 12 AND b != 'foo'; + +explain SELECT * FROM t1 JOIN t2 WHERE a = c AND pk BETWEEN 4 AND 7 AND a BETWEEN 2 AND 12 AND b != 'foo'; + +SET optimizer_switch='rowid_filter=off'; + +SELECT * FROM t1 JOIN t2 WHERE a = c AND pk BETWEEN 4 AND 7 AND a BETWEEN 2 AND 12 AND b != 'foo'; + +SET @@optimizer_switch=@save_optimizer_switch; + +# Cleanup +DROP TABLE t1, t2; + +--echo # +--echo # MDEV-28846: Poor performance when rowid filter contains no elements +--echo # + +--source include/have_sequence.inc + +create table t1 ( + pk int primary key auto_increment, + nm varchar(32), + fl1 tinyint default 0, + fl2 tinyint default 0, + index idx1(nm, fl1), + index idx2(fl2) +) engine=myisam; + +create table name ( + pk int primary key auto_increment, + nm bigint +) engine=myisam; + +create table flag2 ( + pk int primary key auto_increment, + fl2 tinyint +) engine=myisam; + +insert into name(nm) select seq from seq_1_to_1000 order by rand(17); +insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); + +insert into t1(nm,fl2) + select nm, fl2 from name, flag2 where name.pk = flag2.pk; + +analyze table t1 persistent for all; + +let $a= +`select concat((select nm from t1 where fl2=0 order by RAND(13) limit 1),'%')`; +eval select '$a' as a; + +set optimizer_switch='rowid_filter=on'; +eval +explain +select * from t1 where nm like '$a' AND fl2 = 0; +--source include/analyze-format.inc +eval +analyze format=json +select * from t1 where nm like '$a' AND fl2 = 0; +eval +select * from t1 where nm like '$a' AND fl2 = 0; + +truncate table name; +truncate table flag2; +truncate table t1; + +insert into name(nm) select seq from seq_1_to_1000 order by rand(17); +insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); + +insert into t1(nm,fl2) + select nm, fl2 from name, flag2 where name.pk = flag2.pk; + +analyze table t1 persistent for all; + +set optimizer_switch='rowid_filter=off'; +eval +explain +select * from t1 where nm like '$a' AND fl2 = 0; +--source include/analyze-format.inc +eval +analyze format=json +select * from t1 where nm like '$a' AND fl2 = 0; +eval +select * from t1 where nm like '$a' AND fl2 = 0; + +truncate table name; +truncate table flag2; +truncate table t1; + +insert into name(nm) select seq from seq_1_to_1000 order by rand(17); +insert into flag2(fl2) select seq mod 10 from seq_1_to_1000 order by rand(19); + +insert into t1(nm,fl2) + select nm, fl2 from name, flag2 where name.pk = flag2.pk; + +analyze table t1 persistent for all; + +let $a= +`select concat((select nm from t1 where fl2=0 order by RAND(13) limit 1),'%')`; +eval select '$a' as a; + +set optimizer_switch='rowid_filter=on'; +eval +explain +select * from t1 where nm like '$a' AND fl2 = 0; +eval +select * from t1 where nm like '$a' AND fl2 = 0; + +truncate table name; +truncate table flag2; +truncate table t1; + +insert into name(nm) select seq from seq_1_to_10000 order by rand(17); +insert into flag2(fl2) select seq mod 100 from seq_1_to_10000 order by rand(19); + +insert into t1(nm,fl2) + select nm, fl2 from name, flag2 where name.pk = flag2.pk; + +analyze table t1 persistent for all; + +let $a= +`select concat(left((select nm from t1 where fl2=0 order by RAND(13) limit 1),2),'%')`; +eval select '$a' as a; + +set optimizer_switch='rowid_filter=on'; +eval +explain +select * from t1 where nm like '$a' AND fl2 = 0; +--source include/analyze-format.inc +eval +analyze format=json +select * from t1 where nm like '$a' AND fl2 = 0; +eval +select * from t1 where nm like '$a' AND fl2 = 0; + +drop table name, flag2; +drop table t1; + +# This test shows that if the container is empty there are no lookups into it + +create table t1 ( + pk int primary key auto_increment, + nm char(255), + fl1 tinyint default 0, + fl2 int default 0, + index idx1(nm, fl1), + index idx2(fl2) +) engine=myisam; + +create table name ( + pk int primary key auto_increment, + nm bigint +) engine=myisam; + +create table flag2 ( + pk int primary key auto_increment, + fl2 int +) engine=myisam; + +insert into name(nm) select seq from seq_1_to_10000 order by rand(17); +insert into flag2(fl2) select seq mod 10 from seq_1_to_10000 order by rand(19); + +insert into t1(nm,fl2) + select nm, fl2 from name, flag2 where name.pk = flag2.pk; + +analyze table t1 persistent for all; + +let $q= +select * from t1 +where +( + nm like '3400%' or nm like '3402%' or nm like '3403%' or + nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or + nm like '3409%' or + nm like '3411%' or nm like '3412%' or nm like '3413%' or + nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or + nm like '3418%' or nm like '3419%' or + nm like '3421%' or nm like '3422%' or nm like '3423%' or + nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or + nm like '3428%' or nm like '3429%' or + nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or + nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or + nm like '3439%' or + nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or + nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or + nm like '3448%' +) and fl2 = 0; + +eval $q; +--source include/analyze-format.inc +eval analyze format=json $q; + +create table t0 select * from t1 where nm like '34%'; +delete from t1 using t1,t0 where t1.nm=t0.nm; +--source include/analyze-format.inc +eval analyze format=json $q; + +drop table t0; + +set optimizer_switch='rowid_filter=default'; + +drop table name, flag2; +drop table t1; diff --git a/mysql-test/main/rowid_filter_myisam_debug.result b/mysql-test/main/rowid_filter_myisam_debug.result index 75a8fad6947..d68714cc303 100644 --- a/mysql-test/main/rowid_filter_myisam_debug.result +++ b/mysql-test/main/rowid_filter_myisam_debug.result @@ -1,8 +1,10 @@ # # MDEV-22761 KILL QUERY during rowid_filter, crashes # +create table t1(a int); +insert into t1 select seq from seq_1_to_1000; create table t2(a int); -insert into t2 select * from seq_0_to_99; +insert into t2 select seq from seq_1_to_100; CREATE TABLE t3 ( key1 int , key2 int, @@ -10,16 +12,11 @@ filler varchar(255), KEY (key1), KEY (key2) ); +insert into t3 select seq,seq, 'filler-data-filler-data' from seq_1_to_2000; select engine from information_schema.tables where table_schema=database() and table_name='t3'; engine MyISAM -insert into t3 -select -A.seq, -B.seq, -'filler-data-filler-data' -from seq_0_to_99 A, seq_0_to_99 B; analyze table t2,t3; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected @@ -29,14 +26,14 @@ test.t3 analyze status Table is already up to date explain select * from t2, t3 where -t3.key1=t2.a and t3.key2 in (2,3); +t3.key1=t2.a and t3.key2 in (2,3,4,5,6,7,8,9,10); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 100 Using where -1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 100 (2%) Using where; Using rowid filter +1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 1 (0%) Using where; Using rowid filter set debug_sync='handler_rowid_filter_check SIGNAL at_rowid_filter_check WAIT_FOR go'; select * from t2, t3 where -t3.key1=t2.a and t3.key2 in (2,3); +t3.key1=t2.a and t3.key2 in (2,3,4,5,6,7,8,9,10); connect con1, localhost, root,,; set debug_sync='now WAIT_FOR at_rowid_filter_check'; kill query $target_id; @@ -45,4 +42,4 @@ connection default; disconnect con1; ERROR 70100: Query execution was interrupted set debug_sync='RESET'; -drop table t2,t3; +drop table t1,t2,t3; diff --git a/mysql-test/main/select.result b/mysql-test/main/select.result index 93687056c91..bf19d5e9b4e 100644 --- a/mysql-test/main/select.result +++ b/mysql-test/main/select.result @@ -603,6 +603,31 @@ explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +# +# Some test with ORDER BY and limit +# +explain select count(*) from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index period period 4 NULL 41810 Using index +1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using index +explain select sum(t1.price+t3.price) from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=0; explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort @@ -615,6 +640,10 @@ explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period l id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index period period 4 NULL 1 1 SIMPLE t3 ref period period 4 test.t1.period 4181 +set @@join_cache_level=@save_join_cache_level; +# +# Search with a constant table. +# select period from t1; period 9410 @@ -1378,18 +1407,28 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t2 where fld1=999999; +# +# Test left join optimization +# +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=0; explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +set @@join_cache_level=@save_join_cache_level; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where @@ -1426,6 +1465,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +# +# Joins with forms. +# select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; companynr companynr 37 36 @@ -2364,16 +2406,16 @@ insert into t1 values (1,2), (2,2), (3,2), (4,2); insert into t2 values (1,3), (2,3), (3,4), (4,4); explain select * from t1 left join t2 on a=c where d in (4); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref c,d d 5 const 2 -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ref a a 5 test.t2.c 1 select * from t1 left join t2 on a=c where d in (4); a b c d 3 2 3 4 4 2 4 4 explain select * from t1 left join t2 on a=c where d = 4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref c,d d 5 const 2 -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ref a a 5 test.t2.c 1 select * from t1 left join t2 on a=c where d = 4; a b c d 3 2 3 4 @@ -2400,11 +2442,11 @@ INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five'); EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where +1 SIMPLE t2 ref a a 23 test.t1.a 1 Using where EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where +1 SIMPLE t2 ref a a 23 test.t1.a 1 Using where DROP TABLE t1, t2; CREATE TABLE t1 ( city char(30) ); INSERT INTO t1 VALUES ('London'); @@ -3479,7 +3521,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where +1 SIMPLE t1 range|filter PRIMARY,b b|PRIMARY 5|4 NULL 3 (90%) Using index condition; Using where; Using rowid filter 1 SIMPLE t2 ref c c 5 test.t1.a 2 DROP TABLE t1, t2; create table t1 ( @@ -3597,7 +3639,7 @@ CREATE TABLE t1(id int PRIMARY KEY, b int, e int); CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a)); CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c)); INSERT INTO t1 VALUES -(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79), +(1,10,19), (2,20,22), (4,41,42), (9,39,95), (7, 77,79), (6,63,67), (5,55,58), (3,38,39), (8,81,89); INSERT INTO t2 VALUES (21,210), (41,410), (82,820), (83,830), (84,840), @@ -3616,7 +3658,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND @@ -3624,7 +3666,15 @@ t3.a=t2.a AND t3.c IN ('bb','ee') ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter +EXPLAIN +SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 +WHERE t1.id = 9 AND t2.i BETWEEN t1.b AND t1.e AND +t3.a=t2.a AND t3.c IN ('bb','ee'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 range si si 5 NULL 13 Using index condition; Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter EXPLAIN SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3632,7 +3682,7 @@ t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3640,7 +3690,7 @@ t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter DROP TABLE t1,t2,t3; CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int); CREATE TABLE t2 ( f11 int PRIMARY KEY ); @@ -3721,7 +3771,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx2|idx1 4|5 const 2 (27%) Using where; Using rowid filter EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra @@ -3744,7 +3794,7 @@ EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND (ID2_with_null=1 OR ID2_with_null=2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using rowid filter DROP TABLE t1; CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts)); INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00"); @@ -3876,7 +3926,7 @@ cc 3 7 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where +1 SIMPLE t2 ref name name 6 test.t1.name 1 Using where SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; name name n ccc NULL NULL @@ -3969,7 +4019,7 @@ cc 3 7 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where +1 SIMPLE t2 ref name name 6 test.t1.name 1 Using where SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; name name n ccc NULL NULL diff --git a/mysql-test/main/select.test b/mysql-test/main/select.test index 823aa0d54c9..95b66d69255 100644 --- a/mysql-test/main/select.test +++ b/mysql-test/main/select.test @@ -1461,17 +1461,26 @@ select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr orde explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3; -# -# Some test with ORDER BY and limit -# +--echo # +--echo # Some test with ORDER BY and limit +--echo # + +explain select count(*) from t3 as t1,t3 where t1.period=t3.period order by t3.period; +explain select sum(t1.price+t3.price) from t3 as t1,t3 where t1.period=t3.period order by t3.period; explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=0; +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; +explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; +set @@join_cache_level=@save_join_cache_level; -# -# Search with a constant table. -# +--echo # +--echo # Search with a constant table. +--echo # select period from t1; select period from t1 where period=1900; @@ -1532,7 +1541,6 @@ INSERT INTO t4 (companynr, companyname) VALUES (68,'company 10'); INSERT INTO t4 (companynr, companyname) VALUES (50,'company 11'); INSERT INTO t4 (companynr, companyname) VALUES (00,'Unknown'); --enable_query_log - # # Test of stright join to force a full join. # @@ -1564,12 +1572,17 @@ explain select companynr,companyname from t2 left join t4 using (companynr) wher explain select companynr,companyname from t4 left join t2 using (companynr) where companynr is null; delete from t2 where fld1=999999; -# -# Test left join optimization +--echo # +--echo # Test left join optimization +--echo # +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=0; explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; +set @@join_cache_level=@save_join_cache_level; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; @@ -1583,9 +1596,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; -# -# Joins with forms. -# +--echo # +--echo # Joins with forms. +--echo # select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; @@ -3140,7 +3153,7 @@ CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a)); CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c)); INSERT INTO t1 VALUES - (1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79), + (1,10,19), (2,20,22), (4,41,42), (9,39,95), (7, 77,79), (6,63,67), (5,55,58), (3,38,39), (8,81,89); INSERT INTO t2 VALUES (21,210), (41,410), (82,820), (83,830), (84,840), @@ -3162,6 +3175,11 @@ SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND t3.a=t2.a AND t3.c IN ('bb','ee') ; +EXPLAIN +SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 + WHERE t1.id = 9 AND t2.i BETWEEN t1.b AND t1.e AND + t3.a=t2.a AND t3.c IN ('bb','ee'); + EXPLAIN SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND diff --git a/mysql-test/main/select_jcl6.result b/mysql-test/main/select_jcl6.result index c1098e660cd..4001a6db81a 100644 --- a/mysql-test/main/select_jcl6.result +++ b/mysql-test/main/select_jcl6.result @@ -614,18 +614,47 @@ explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +# +# Some test with ORDER BY and limit +# +explain select count(*) from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index period period 4 NULL 41810 Using index +1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using index +explain select sum(t1.price+t3.price) from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort -1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using temporary; Using filesort -1 SIMPLE t1 ref period period 4 test.t3.period 4181 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort -1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=0; +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort +1 SIMPLE t3 ref period period 4 test.t1.period 4181 +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 index period period 4 NULL 1 +1 SIMPLE t1 ref period period 4 test.t3.period 4181 +explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index period period 4 NULL 1 +1 SIMPLE t3 ref period period 4 test.t1.period 4181 +set @@join_cache_level=@save_join_cache_level; +# +# Search with a constant table. +# select period from t1; period 9410 @@ -1389,18 +1418,28 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t2 where fld1=999999; +# +# Test left join optimization +# +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=0; explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +set @@join_cache_level=@save_join_cache_level; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where @@ -1437,6 +1476,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where 1 SIMPLE t2 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join) +# +# Joins with forms. +# select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; companynr companynr 37 36 @@ -2375,16 +2417,16 @@ insert into t1 values (1,2), (2,2), (3,2), (4,2); insert into t2 values (1,3), (2,3), (3,4), (4,4); explain select * from t1 left join t2 on a=c where d in (4); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref c,d d 5 const 2 -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ref a a 5 test.t2.c 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan select * from t1 left join t2 on a=c where d in (4); a b c d 3 2 3 4 4 2 4 4 explain select * from t1 left join t2 on a=c where d = 4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref c,d d 5 const 2 -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ref a a 5 test.t2.c 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan select * from t1 left join t2 on a=c where d = 4; a b c d 3 2 3 4 @@ -2411,11 +2453,11 @@ INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five'); EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where +1 SIMPLE t2 ref a a 23 test.t1.a 1 Using where EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where +1 SIMPLE t2 ref a a 23 test.t1.a 1 Using where DROP TABLE t1, t2; CREATE TABLE t1 ( city char(30) ); INSERT INTO t1 VALUES ('London'); @@ -3490,7 +3532,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE t1 range|filter PRIMARY,b b|PRIMARY 5|4 NULL 3 (90%) Using index condition; Using where; Rowid-ordered scan; Using rowid filter 1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan DROP TABLE t1, t2; create table t1 ( @@ -3608,7 +3650,7 @@ CREATE TABLE t1(id int PRIMARY KEY, b int, e int); CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a)); CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c)); INSERT INTO t1 VALUES -(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79), +(1,10,19), (2,20,22), (4,41,42), (9,39,95), (7, 77,79), (6,63,67), (5,55,58), (3,38,39), (8,81,89); INSERT INTO t2 VALUES (21,210), (41,410), (82,820), (83,830), (84,840), @@ -3627,7 +3669,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where; Rowid-ordered scan -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND @@ -3635,7 +3677,15 @@ t3.a=t2.a AND t3.c IN ('bb','ee') ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where; Rowid-ordered scan -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter +EXPLAIN +SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 +WHERE t1.id = 9 AND t2.i BETWEEN t1.b AND t1.e AND +t3.a=t2.a AND t3.c IN ('bb','ee'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t3 range PRIMARY,ci ci 5 NULL 6 Using index condition; Rowid-ordered scan +1 SIMPLE t2 hash_range si #hash#$hj:si 5:5 test.t3.a 13 Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join) EXPLAIN SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3643,7 +3693,7 @@ t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where; Rowid-ordered scan -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3651,7 +3701,7 @@ t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where; Rowid-ordered scan -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter DROP TABLE t1,t2,t3; CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int); CREATE TABLE t2 ( f11 int PRIMARY KEY ); @@ -3732,7 +3782,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx2|idx1 4|5 const 2 (27%) Using where; Using rowid filter EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra @@ -3755,7 +3805,7 @@ EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND (ID2_with_null=1 OR ID2_with_null=2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using rowid filter DROP TABLE t1; CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts)); INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00"); @@ -3887,7 +3937,7 @@ cc 3 7 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where +1 SIMPLE t2 ref name name 6 test.t1.name 1 Using where SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; name name n ccc NULL NULL @@ -3980,7 +4030,7 @@ cc 3 7 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where +1 SIMPLE t2 ref name name 6 test.t1.name 1 Using where SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; name name n ccc NULL NULL diff --git a/mysql-test/main/select_pkeycache.result b/mysql-test/main/select_pkeycache.result index 93687056c91..bf19d5e9b4e 100644 --- a/mysql-test/main/select_pkeycache.result +++ b/mysql-test/main/select_pkeycache.result @@ -603,6 +603,31 @@ explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +# +# Some test with ORDER BY and limit +# +explain select count(*) from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index period period 4 NULL 41810 Using index +1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using index +explain select sum(t1.price+t3.price) from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t3 ALL period NULL NULL NULL 41810 Using where; Using join buffer (flat, BNL join) +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=0; explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort @@ -615,6 +640,10 @@ explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period l id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index period period 4 NULL 1 1 SIMPLE t3 ref period period 4 test.t1.period 4181 +set @@join_cache_level=@save_join_cache_level; +# +# Search with a constant table. +# select period from t1; period 9410 @@ -1378,18 +1407,28 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t2 where fld1=999999; +# +# Test left join optimization +# +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=0; explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +set @@join_cache_level=@save_join_cache_level; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where @@ -1426,6 +1465,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +# +# Joins with forms. +# select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; companynr companynr 37 36 @@ -2364,16 +2406,16 @@ insert into t1 values (1,2), (2,2), (3,2), (4,2); insert into t2 values (1,3), (2,3), (3,4), (4,4); explain select * from t1 left join t2 on a=c where d in (4); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref c,d d 5 const 2 -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ref a a 5 test.t2.c 1 select * from t1 left join t2 on a=c where d in (4); a b c d 3 2 3 4 4 2 4 4 explain select * from t1 left join t2 on a=c where d = 4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ref c,d d 5 const 2 -1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ref a a 5 test.t2.c 1 select * from t1 left join t2 on a=c where d = 4; a b c d 3 2 3 4 @@ -2400,11 +2442,11 @@ INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five'); EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where +1 SIMPLE t2 ref a a 23 test.t1.a 1 Using where EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref a a 23 test.t1.a 2 Using where +1 SIMPLE t2 ref a a 23 test.t1.a 1 Using where DROP TABLE t1, t2; CREATE TABLE t1 ( city char(30) ); INSERT INTO t1 VALUES ('London'); @@ -3479,7 +3521,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where +1 SIMPLE t1 range|filter PRIMARY,b b|PRIMARY 5|4 NULL 3 (90%) Using index condition; Using where; Using rowid filter 1 SIMPLE t2 ref c c 5 test.t1.a 2 DROP TABLE t1, t2; create table t1 ( @@ -3597,7 +3639,7 @@ CREATE TABLE t1(id int PRIMARY KEY, b int, e int); CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a)); CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c)); INSERT INTO t1 VALUES -(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79), +(1,10,19), (2,20,22), (4,41,42), (9,39,95), (7, 77,79), (6,63,67), (5,55,58), (3,38,39), (8,81,89); INSERT INTO t2 VALUES (21,210), (41,410), (82,820), (83,830), (84,840), @@ -3616,7 +3658,7 @@ t3.a=t2.a AND t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND @@ -3624,7 +3666,15 @@ t3.a=t2.a AND t3.c IN ('bb','ee') ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter +EXPLAIN +SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 +WHERE t1.id = 9 AND t2.i BETWEEN t1.b AND t1.e AND +t3.a=t2.a AND t3.c IN ('bb','ee'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 range si si 5 NULL 13 Using index condition; Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter EXPLAIN SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3632,7 +3682,7 @@ t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter EXPLAIN SELECT t3.a FROM t1,t2,t3 WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND @@ -3640,7 +3690,7 @@ t3.c IN ('bb','ee'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where -1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t3 eq_ref|filter PRIMARY,ci PRIMARY|ci 4|5 test.t2.a 1 (30%) Using where; Using rowid filter DROP TABLE t1,t2,t3; CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int); CREATE TABLE t2 ( f11 int PRIMARY KEY ); @@ -3721,7 +3771,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx2|idx1 4|5 const 2 (27%) Using where; Using rowid filter EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; id select_type table type possible_keys key key_len ref rows Extra @@ -3744,7 +3794,7 @@ EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID1_with_null IS NULL AND (ID2_with_null=1 OR ID2_with_null=2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where +1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using rowid filter DROP TABLE t1; CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts)); INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00"); @@ -3876,7 +3926,7 @@ cc 3 7 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where +1 SIMPLE t2 ref name name 6 test.t1.name 1 Using where SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; name name n ccc NULL NULL @@ -3969,7 +4019,7 @@ cc 3 7 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 -1 SIMPLE t2 ref name name 6 test.t1.name 2 Using where +1 SIMPLE t2 ref name name 6 test.t1.name 1 Using where SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; name name n ccc NULL NULL diff --git a/mysql-test/main/select_safe.result b/mysql-test/main/select_safe.result index 649e2dc484e..a16d5439f48 100644 --- a/mysql-test/main/select_safe.result +++ b/mysql-test/main/select_safe.result @@ -67,6 +67,7 @@ test.t1 analyze status OK insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); insert into t1 values (null,"b"),(null,"b"),(null,"c"),(null,"c"),(null,"d"),(null,"d"),(null,"e"),(null,"e"),(null,"a"),(null,"e"); insert into t1 values (null,"x"),(null,"x"),(null,"y"),(null,"y"),(null,"z"),(null,"z"),(null,"v"),(null,"v"),(null,"a"),(null,"v"); +set @@optimizer_where_cost=0.3; explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL b NULL NULL NULL 11 diff --git a/mysql-test/main/select_safe.test b/mysql-test/main/select_safe.test index c76e337cd10..b9788cf2eb2 100644 --- a/mysql-test/main/select_safe.test +++ b/mysql-test/main/select_safe.test @@ -60,6 +60,7 @@ analyze table t1; insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); insert into t1 values (null,"b"),(null,"b"),(null,"c"),(null,"c"),(null,"d"),(null,"d"),(null,"e"),(null,"e"),(null,"a"),(null,"e"); insert into t1 values (null,"x"),(null,"x"),(null,"y"),(null,"y"),(null,"z"),(null,"z"),(null,"v"),(null,"v"),(null,"a"),(null,"v"); +set @@optimizer_where_cost=0.3; explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b; set MAX_SEEKS_FOR_KEY=1; explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b; diff --git a/mysql-test/main/selectivity.result b/mysql-test/main/selectivity.result index 7e8a4aeb083..e8ec0c30e80 100644 --- a/mysql-test/main/selectivity.result +++ b/mysql-test/main/selectivity.result @@ -52,7 +52,7 @@ part, supplier, partsupp, nation, region where p_partkey = ps_partkey and s_suppkey = ps_suppkey -and p_size = 9 +and (p_size = 9 or p_size =19999) and p_type like '%TIN' and s_nationkey = n_nationkey and n_regionkey = r_regionkey @@ -72,18 +72,18 @@ and r_name = 'ASIA' order by s_acctbal desc, n_name, s_name, p_partkey; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.31 Using where; Using temporary; Using filesort -1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using temporary; Using filesort +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.63 Using where; Using join buffer (flat, BNL join) +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where 1 PRIMARY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where -1 PRIMARY region eq_ref PRIMARY PRIMARY 4 dbt3_s001.nation.n_regionkey 1 20.00 Using where -2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where -2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 +2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +2 DEPENDENT SUBQUERY region eq_ref PRIMARY PRIMARY 4 dbt3_s001.nation.n_regionkey 1 20.00 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`part`.`p_size` = 9 and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`region`.`r_regionkey` = `dbt3_s001`.`nation`.`n_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` +Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and (`dbt3_s001`.`part`.`p_size` = 9 or `dbt3_s001`.`part`.`p_size` = 19999) and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`region`.`r_regionkey` = `dbt3_s001`.`nation`.`n_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` set optimizer_use_condition_selectivity=4; explain extended select @@ -118,13 +118,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 2.08 Using where; Using join buffer (flat, BNL join) 1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 100.00 Using where -2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where -2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 +2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +2 DEPENDENT SUBQUERY region eq_ref PRIMARY PRIMARY 4 dbt3_s001.nation.n_regionkey 1 20.00 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_suppkey` = `dbt3_s001`.`supplier`.`s_suppkey` and `dbt3_s001`.`part`.`p_size` = 9 and `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` +Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_suppkey` = `dbt3_s001`.`supplier`.`s_suppkey` and `dbt3_s001`.`part`.`p_size` = 9 and `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`region`.`r_regionkey` = `dbt3_s001`.`nation`.`n_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` === Q15 === create view revenue0 (supplier_no, total_revenue) as select l_suppkey, sum(l_extendedprice * (1 - l_discount)) @@ -490,7 +490,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 100.00 Using where 2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 Using where -4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 Using where +4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 15.14 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2 @@ -541,8 +541,8 @@ limit 10; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 -1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 4.17 Using where; Start temporary; Using join buffer (flat, BNL join) -1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 100.00 Using where; End temporary +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 4.17 Using where +1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 11.99 Using where; FirstMatch(supplier) 4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 15.14 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 @@ -597,7 +597,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 7.03 Using where -1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 100.00 Using where; FirstMatch(supplier) +1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 7.11 Using where; FirstMatch(supplier) 4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 15.14 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 @@ -652,7 +652,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 7.81 Using where -1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 100.00 Using where; FirstMatch(supplier) +1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 6.40 Using where; FirstMatch(supplier) 4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 15.14 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 @@ -707,7 +707,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 7.81 Using where -1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 100.00 Using where; FirstMatch(supplier) +1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 6.40 Using where; FirstMatch(supplier) 4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 15.14 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 @@ -755,7 +755,7 @@ EXPLAIN EXTENDED SELECT * FROM v1 INNER JOIN t2 ON ( a = c AND b = d ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where -1 SIMPLE t2 ref idx idx 5 test.t1.b 2 100.00 Using where +1 SIMPLE t2 ref idx idx 5 test.t1.b 1 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t2`.`d` = `test`.`t1`.`b` SELECT * FROM v1 INNER JOIN t2 ON ( a = c AND b = d ); @@ -1641,27 +1641,51 @@ drop function f1; # create table t1 (a int, b int, key (b), key (a)); insert into t1 -select (rand(1)*1000)/10, (rand(1001)*1000)/20 from seq_1_to_1000; -analyze table t1 persistent for all; +select (rand(1)*1000)/30, (rand(1001)*1000)/40 from seq_1_to_1000; +analyze table t1 ; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status Table is already up to date +select count(*) from t1 where b=2; +count(*) +42 +select count(*) from t1 where a in (17,51,5); +count(*) +62 # Check what info the optimizer has about selectivities explain extended select * from t1 use index () where a in (17,51,5); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.90 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 6.20 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`a` in (17,51,5) explain extended select * from t1 use index () where b=2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.40 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 4.20 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`b` = 2 # Now, the equality is used for ref access, while the range condition # gives selectivity data explain extended select * from t1 where a in (17,51,5) and b=2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ref b,a b 5 const 24 2.90 Using where +1 SIMPLE t1 ref|filter b,a b|a 5|5 const 42 (6%) 6.30 Using where; Using rowid filter +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (17,51,5) +truncate table t1; +insert into t1 +select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000; +analyze table t1 ; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +select count(*) from t1 where b=2; +count(*) +59 +select count(*) from t1 where a in (17,51,5); +count(*) +29 +explain extended select * from t1 where a in (17,51,5) and b=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range|filter b,a a|b 5|5 NULL 29 (6%) 5.80 Using index condition; Using where; Using rowid filter Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (17,51,5) drop table t1; @@ -1790,7 +1814,7 @@ set optimizer_use_condition_selectivity=2; explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3 where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range a a 10 NULL 9 9.00 Using index condition; Using where +1 SIMPLE t1 range a a 10 NULL 9 100.00 Using index condition; Using where 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00 Warnings: @@ -1808,6 +1832,18 @@ b a a b 7 7 8 8 8 8 9 9 9 9 10 10 +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3 +where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range a a 10 NULL 9 100.00 Using index condition; Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00 +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t1`.`c` and `test`.`t3`.`a` = `test`.`t1`.`d` and `test`.`t1`.`a` = 50 and `test`.`t1`.`b` <= 100 set optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; drop table t1,t2,t3; # @@ -1856,7 +1892,7 @@ WHERE A.a=t1.a AND t2.b < 20); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 100 Using where 2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 -2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where +2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (10%) Using where; Using rowid filter EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1 @@ -1868,7 +1904,7 @@ WHERE A.a=t1.a AND t2.b < 20); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 100 Using where 2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 -2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where +2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (10%) Using where; Using rowid filter set optimizer_switch= @save_optimizer_switch; set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; drop table t1,t2; @@ -1947,3 +1983,31 @@ set use_stat_tables= @save_use_stat_tables; DROP TABLE t1; # End of 10.2 tests set @@global.histogram_size=@save_histogram_size; +# +# MDEV-20595 +# Assertion `0 < sel && sel <= 2.0' failed in table_cond_selectivity +# +create table t1 (id int, a int, PRIMARY KEY(id), key(a)); +insert into t1 select seq,seq from seq_1_to_100; +create table t2 (id int, a int, b int, PRIMARY KEY(id), key(a), key(b)); +insert into t2 select seq,seq,seq from seq_1_to_100; +set optimizer_use_condition_selectivity=2; +EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1 +1 SIMPLE B ref a a 5 const 1 +set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +drop table t1,t2; +# +# MDEV-30360 Assertion `cond_selectivity <= 1.000000001' failed in get_range_limit_read_cost +# with LIMIT .. OFFSET +# +CREATE TABLE t1 (a INT, b VARCHAR(1), KEY(b), KEY(a)) engine=myisam; +INSERT INTO t1 VALUES +(3,'a'),(2,'g'),(5,'v'),(9,'n'),(6,'u'), +(7,'s'),(0,'z'),(3,'z'),(NULL,'m'),(6,'r'); +CREATE TABLE t2 (pk INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); +SELECT STRAIGHT_JOIN pk FROM t1 JOIN t2 ON a = pk WHERE b >= 'A' ORDER BY t2.pk LIMIT 8 OFFSET 1; +pk +DROP TABLE t1, t2; diff --git a/mysql-test/main/selectivity.test b/mysql-test/main/selectivity.test index 4e4513d09d6..d775f8e4370 100644 --- a/mysql-test/main/selectivity.test +++ b/mysql-test/main/selectivity.test @@ -67,7 +67,9 @@ customer, lineitem, nation, orders, part, partsupp, region, supplier; --enable_query_log --echo === Q2 === - +# "or p_size =19999" is added to avoid symmetry between +# region (5 rows * 20% selectivity) = 1 and +# part (200 rows * 0.5% selectivity) = 1 set optimizer_use_condition_selectivity=5; explain extended select @@ -77,7 +79,7 @@ from where p_partkey = ps_partkey and s_suppkey = ps_suppkey - and p_size = 9 + and (p_size = 9 or p_size =19999) and p_type like '%TIN' and s_nationkey = n_nationkey and n_regionkey = r_regionkey @@ -1111,8 +1113,10 @@ drop function f1; --echo # create table t1 (a int, b int, key (b), key (a)); insert into t1 -select (rand(1)*1000)/10, (rand(1001)*1000)/20 from seq_1_to_1000; -analyze table t1 persistent for all; +select (rand(1)*1000)/30, (rand(1001)*1000)/40 from seq_1_to_1000; +analyze table t1 ; +select count(*) from t1 where b=2; +select count(*) from t1 where a in (17,51,5); --echo # Check what info the optimizer has about selectivities explain extended select * from t1 use index () where a in (17,51,5); @@ -1121,6 +1125,13 @@ explain extended select * from t1 use index () where b=2; --echo # Now, the equality is used for ref access, while the range condition --echo # gives selectivity data explain extended select * from t1 where a in (17,51,5) and b=2; +truncate table t1; +insert into t1 +select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000; +analyze table t1 ; +select count(*) from t1 where b=2; +select count(*) from t1 where a in (17,51,5); +explain extended select * from t1 where a in (17,51,5) and b=2; drop table t1; set use_stat_tables= @save_use_stat_tables; @@ -1232,17 +1243,16 @@ eval $query; set optimizer_use_condition_selectivity=2; eval explain extended $query; eval $query; +analyze table t1; +eval explain extended $query; set optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; drop table t1,t2,t3; - --echo # --echo # MDEV-20519: Query plan regression with optimizer_use_condition_selectivity=4 --echo # - - create table t1 (id int, a int, PRIMARY KEY(id), key(a)); insert into t1 select seq,seq from seq_1_to_100; @@ -1334,3 +1344,35 @@ DROP TABLE t1; # --source include/restore_charset.inc set @@global.histogram_size=@save_histogram_size; + +--echo # +--echo # MDEV-20595 +--echo # Assertion `0 < sel && sel <= 2.0' failed in table_cond_selectivity +--echo # + +create table t1 (id int, a int, PRIMARY KEY(id), key(a)); +insert into t1 select seq,seq from seq_1_to_100; +create table t2 (id int, a int, b int, PRIMARY KEY(id), key(a), key(b)); +insert into t2 select seq,seq,seq from seq_1_to_100; + +set optimizer_use_condition_selectivity=2; +EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65; +set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +drop table t1,t2; + +--echo # +--echo # MDEV-30360 Assertion `cond_selectivity <= 1.000000001' failed in get_range_limit_read_cost +--echo # with LIMIT .. OFFSET +--echo # + +CREATE TABLE t1 (a INT, b VARCHAR(1), KEY(b), KEY(a)) engine=myisam; +INSERT INTO t1 VALUES +(3,'a'),(2,'g'),(5,'v'),(9,'n'),(6,'u'), +(7,'s'),(0,'z'),(3,'z'),(NULL,'m'),(6,'r'); + +CREATE TABLE t2 (pk INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); + +SELECT STRAIGHT_JOIN pk FROM t1 JOIN t2 ON a = pk WHERE b >= 'A' ORDER BY t2.pk LIMIT 8 OFFSET 1; + +DROP TABLE t1, t2; diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index 76093f16cd7..274ba62329d 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -57,7 +57,7 @@ part, supplier, partsupp, nation, region where p_partkey = ps_partkey and s_suppkey = ps_suppkey -and p_size = 9 +and (p_size = 9 or p_size =19999) and p_type like '%TIN' and s_nationkey = n_nationkey and n_regionkey = r_regionkey @@ -77,18 +77,18 @@ and r_name = 'ASIA' order by s_acctbal desc, n_name, s_name, p_partkey; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.31 Using where; Using temporary; Using filesort -1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using temporary; Using filesort +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.63 Using where; Using join buffer (flat, BNL join) 1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where 1 PRIMARY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where -2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where 2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +2 DEPENDENT SUBQUERY region eq_ref PRIMARY PRIMARY 4 dbt3_s001.nation.n_regionkey 1 20.00 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`part`.`p_size` = 9 and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` +Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and (`dbt3_s001`.`part`.`p_size` = 9 or `dbt3_s001`.`part`.`p_size` = 19999) and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`region`.`r_regionkey` = `dbt3_s001`.`nation`.`n_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` set optimizer_use_condition_selectivity=4; explain extended select @@ -123,13 +123,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where 1 PRIMARY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where -2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where 2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +2 DEPENDENT SUBQUERY region eq_ref PRIMARY PRIMARY 4 dbt3_s001.nation.n_regionkey 1 20.00 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`part`.`p_size` = 9 and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` +Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`part`.`p_size` = 9 and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`region`.`r_regionkey` = `dbt3_s001`.`nation`.`n_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` === Q15 === create view revenue0 (supplier_no, total_revenue) as select l_suppkey, sum(l_extendedprice * (1 - l_discount)) @@ -171,7 +171,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY supplier index PRIMARY PRIMARY 4 NULL 10 100.00 1 PRIMARY ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where 3 DERIVED lineitem range i_l_shipdate,i_l_suppkey i_l_shipdate 4 NULL 229 100.00 Using where; Using temporary; Using filesort -2 SUBQUERY ALL NULL NULL NULL NULL 228 100.00 +2 SUBQUERY ALL NULL NULL NULL NULL 229 100.00 4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 229 100.00 Using where; Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_suppkey` AS `s_suppkey`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`revenue0`.`total_revenue` AS `total_revenue` from `dbt3_s001`.`supplier` join `dbt3_s001`.`revenue0` where `revenue0`.`supplier_no` = `dbt3_s001`.`supplier`.`s_suppkey` and `revenue0`.`total_revenue` = (/* select#2 */ select max(`revenue0`.`total_revenue`) from `dbt3_s001`.`revenue0`) order by `dbt3_s001`.`supplier`.`s_suppkey` @@ -334,7 +334,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index -2 MATERIALIZED lineitem index NULL PRIMARY 8 NULL 6005 100.00 +2 MATERIALIZED lineitem index NULL i_l_orderkey_quantity 13 NULL 6005 100.00 Using index Warnings: Note 1003 /* select#1 */ select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from (/* select#2 */ select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where `dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey` and ``.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey` and `dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey` group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` select @@ -368,7 +368,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index -2 MATERIALIZED lineitem index NULL PRIMARY 8 NULL 6005 100.00 +2 MATERIALIZED lineitem index NULL i_l_orderkey_quantity 13 NULL 6005 100.00 Using index Warnings: Note 1003 /* select#1 */ select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from (/* select#2 */ select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where `dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey` and ``.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey` and `dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey` group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` select @@ -495,7 +495,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 100.00 Using where 2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where -4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 Using where +4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 14.40 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2 @@ -546,14 +546,13 @@ limit 10; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 4.17 Using where -2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 4.17 Using where +1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 11.99 Using where; FirstMatch(supplier) 4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 14.40 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2 -Note 1003 /* select#1 */ select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_name` = 'UNITED STATES' and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_availqty` > <`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((/* select#4 */ select 0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`) from `dbt3_s001`.`lineitem` where `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_shipDATE` >= (cast('1993-01-01' as date)) and `dbt3_s001`.`lineitem`.`l_shipDATE` < (cast('1993-01-01' as date) + interval '1' year))) and `dbt3_s001`.`part`.`p_name` like 'g%' order by `dbt3_s001`.`supplier`.`s_name` limit 10 +Note 1003 /* select#1 */ select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_name` = 'UNITED STATES' and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_suppkey` = `dbt3_s001`.`supplier`.`s_suppkey` and `dbt3_s001`.`partsupp`.`ps_availqty` > <`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((/* select#4 */ select 0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`) from `dbt3_s001`.`lineitem` where `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_shipDATE` >= (cast('1993-01-01' as date)) and `dbt3_s001`.`lineitem`.`l_shipDATE` < (cast('1993-01-01' as date) + interval '1' year))) and `dbt3_s001`.`part`.`p_name` like 'g%' order by `dbt3_s001`.`supplier`.`s_name` limit 10 select sql_calc_found_rows s_name, s_address from supplier, nation @@ -602,14 +601,13 @@ limit 10; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 7.03 Using where -2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 7.03 Using where +1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 7.11 Using where; FirstMatch(supplier) 4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 14.40 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2 -Note 1003 /* select#1 */ select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_name` = 'UNITED STATES' and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_availqty` > <`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((/* select#4 */ select 0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`) from `dbt3_s001`.`lineitem` where `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_shipDATE` >= (cast('1993-01-01' as date)) and `dbt3_s001`.`lineitem`.`l_shipDATE` < (cast('1993-01-01' as date) + interval '1' year))) and `dbt3_s001`.`part`.`p_name` like 'g%' order by `dbt3_s001`.`supplier`.`s_name` limit 10 +Note 1003 /* select#1 */ select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_name` = 'UNITED STATES' and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_suppkey` = `dbt3_s001`.`supplier`.`s_suppkey` and `dbt3_s001`.`partsupp`.`ps_availqty` > <`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((/* select#4 */ select 0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`) from `dbt3_s001`.`lineitem` where `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_shipDATE` >= (cast('1993-01-01' as date)) and `dbt3_s001`.`lineitem`.`l_shipDATE` < (cast('1993-01-01' as date) + interval '1' year))) and `dbt3_s001`.`part`.`p_name` like 'g%' order by `dbt3_s001`.`supplier`.`s_name` limit 10 select sql_calc_found_rows s_name, s_address from supplier, nation @@ -658,14 +656,13 @@ limit 10; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 7.81 Using where -2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 7.81 Using where +1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 6.40 Using where; FirstMatch(supplier) 4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 14.40 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2 -Note 1003 /* select#1 */ select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_name` = 'UNITED STATES' and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_availqty` > <`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((/* select#4 */ select 0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`) from `dbt3_s001`.`lineitem` where `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_shipDATE` >= (cast('1993-01-01' as date)) and `dbt3_s001`.`lineitem`.`l_shipDATE` < (cast('1993-01-01' as date) + interval '1' year))) and `dbt3_s001`.`part`.`p_name` like 'g%' order by `dbt3_s001`.`supplier`.`s_name` limit 10 +Note 1003 /* select#1 */ select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_name` = 'UNITED STATES' and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_suppkey` = `dbt3_s001`.`supplier`.`s_suppkey` and `dbt3_s001`.`partsupp`.`ps_availqty` > <`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((/* select#4 */ select 0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`) from `dbt3_s001`.`lineitem` where `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_shipDATE` >= (cast('1993-01-01' as date)) and `dbt3_s001`.`lineitem`.`l_shipDATE` < (cast('1993-01-01' as date) + interval '1' year))) and `dbt3_s001`.`part`.`p_name` like 'g%' order by `dbt3_s001`.`supplier`.`s_name` limit 10 select sql_calc_found_rows s_name, s_address from supplier, nation @@ -714,14 +711,13 @@ limit 10; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort 1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 7.81 Using where -2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 7.81 Using where +1 PRIMARY partsupp eq_ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 8 dbt3_s001.part.p_partkey,dbt3_s001.supplier.s_suppkey 1 6.40 Using where; FirstMatch(supplier) 4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 14.40 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2 -Note 1003 /* select#1 */ select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_name` = 'UNITED STATES' and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_availqty` > <`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((/* select#4 */ select 0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`) from `dbt3_s001`.`lineitem` where `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_shipDATE` >= (cast('1993-01-01' as date)) and `dbt3_s001`.`lineitem`.`l_shipDATE` < (cast('1993-01-01' as date) + interval '1' year))) and `dbt3_s001`.`part`.`p_name` like 'g%' order by `dbt3_s001`.`supplier`.`s_name` limit 10 +Note 1003 /* select#1 */ select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey` and `dbt3_s001`.`nation`.`n_name` = 'UNITED STATES' and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`partsupp`.`ps_suppkey` = `dbt3_s001`.`supplier`.`s_suppkey` and `dbt3_s001`.`partsupp`.`ps_availqty` > <`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((/* select#4 */ select 0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`) from `dbt3_s001`.`lineitem` where `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_shipDATE` >= (cast('1993-01-01' as date)) and `dbt3_s001`.`lineitem`.`l_shipDATE` < (cast('1993-01-01' as date) + interval '1' year))) and `dbt3_s001`.`part`.`p_name` like 'g%' order by `dbt3_s001`.`supplier`.`s_name` limit 10 select sql_calc_found_rows s_name, s_address from supplier, nation @@ -808,10 +804,9 @@ explain extended select * from t1 where a in ( select b from t2 ) AND ( a > 3 ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 1 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t1`.`a` > 3 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`b` = `test`.`t1`.`a` and `test`.`t1`.`a` > 3 select * from t1 where a in ( select b from t2 ) AND ( a > 3 ); a drop table t1,t2; @@ -946,7 +941,7 @@ set optimizer_switch='index_condition_pushdown=off'; EXPLAIN EXTENDED SELECT * FROM t1, t2 WHERE a > 9; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range a a 5 NULL 1 0.00 Using where +1 SIMPLE t1 range a a 5 NULL 1 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` > 9 @@ -1653,27 +1648,51 @@ drop function f1; # create table t1 (a int, b int, key (b), key (a)); insert into t1 -select (rand(1)*1000)/10, (rand(1001)*1000)/20 from seq_1_to_1000; -analyze table t1 persistent for all; +select (rand(1)*1000)/30, (rand(1001)*1000)/40 from seq_1_to_1000; +analyze table t1 ; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK +select count(*) from t1 where b=2; +count(*) +42 +select count(*) from t1 where a in (17,51,5); +count(*) +62 # Check what info the optimizer has about selectivities explain extended select * from t1 use index () where a in (17,51,5); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.90 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 6.20 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`a` in (17,51,5) explain extended select * from t1 use index () where b=2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.40 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 4.20 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`b` = 2 # Now, the equality is used for ref access, while the range condition # gives selectivity data explain extended select * from t1 where a in (17,51,5) and b=2; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ref b,a b 5 const 24 2.90 Using where +1 SIMPLE t1 ref|filter b,a b|a 5|5 const 42 (6%) 6.30 Using where; Using rowid filter +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (17,51,5) +truncate table t1; +insert into t1 +select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000; +analyze table t1 ; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +select count(*) from t1 where b=2; +count(*) +59 +select count(*) from t1 where a in (17,51,5); +count(*) +29 +explain extended select * from t1 where a in (17,51,5) and b=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range|filter b,a a|b 5|5 NULL 29 (6%) 5.90 Using index condition; Using where; Using rowid filter Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (17,51,5) drop table t1; @@ -1781,7 +1800,7 @@ explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3 where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 10 NULL 11 100.00 Using index condition; Using where -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00 Warnings: Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t1`.`c` and `test`.`t3`.`a` = `test`.`t1`.`d` and `test`.`t1`.`a` = 50 and `test`.`t1`.`b` <= 100 @@ -1802,8 +1821,8 @@ set optimizer_use_condition_selectivity=2; explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3 where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 range a a 10 NULL 11 11.00 Using index condition; Using where -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index +1 SIMPLE t1 range a a 10 NULL 11 100.00 Using index condition; Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00 Warnings: Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t1`.`c` and `test`.`t3`.`a` = `test`.`t1`.`d` and `test`.`t1`.`a` = 50 and `test`.`t1`.`b` <= 100 @@ -1820,6 +1839,18 @@ b a a b 7 7 8 8 8 8 9 9 9 9 10 10 +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3 +where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range a a 10 NULL 11 100.00 Using index condition; Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00 +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t1`.`c` and `test`.`t3`.`a` = `test`.`t1`.`d` and `test`.`t1`.`a` = 50 and `test`.`t1`.`b` <= 100 set optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; drop table t1,t2,t3; # @@ -1868,7 +1899,7 @@ WHERE A.a=t1.a AND t2.b < 20); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index 2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index -2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where +2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (19%) Using where; Using rowid filter EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1 @@ -1880,7 +1911,7 @@ WHERE A.a=t1.a AND t2.b < 20); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index 2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index -2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where +2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (19%) Using where; Using rowid filter set optimizer_switch= @save_optimizer_switch; set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; drop table t1,t2; @@ -1959,6 +1990,34 @@ set use_stat_tables= @save_use_stat_tables; DROP TABLE t1; # End of 10.2 tests set @@global.histogram_size=@save_histogram_size; +# +# MDEV-20595 +# Assertion `0 < sel && sel <= 2.0' failed in table_cond_selectivity +# +create table t1 (id int, a int, PRIMARY KEY(id), key(a)); +insert into t1 select seq,seq from seq_1_to_100; +create table t2 (id int, a int, b int, PRIMARY KEY(id), key(a), key(b)); +insert into t2 select seq,seq,seq from seq_1_to_100; +set optimizer_use_condition_selectivity=2; +EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1 +1 SIMPLE B ref a a 5 const 1 Using index +set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +drop table t1,t2; +# +# MDEV-30360 Assertion `cond_selectivity <= 1.000000001' failed in get_range_limit_read_cost +# with LIMIT .. OFFSET +# +CREATE TABLE t1 (a INT, b VARCHAR(1), KEY(b), KEY(a)) engine=myisam; +INSERT INTO t1 VALUES +(3,'a'),(2,'g'),(5,'v'),(9,'n'),(6,'u'), +(7,'s'),(0,'z'),(3,'z'),(NULL,'m'),(6,'r'); +CREATE TABLE t2 (pk INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); +SELECT STRAIGHT_JOIN pk FROM t1 JOIN t2 ON a = pk WHERE b >= 'A' ORDER BY t2.pk LIMIT 8 OFFSET 1; +pk +DROP TABLE t1, t2; set optimizer_switch=@save_optimizer_switch_for_selectivity_test; set @tmp_ust= @@use_stat_tables; set @tmp_oucs= @@optimizer_use_condition_selectivity; @@ -2162,3 +2221,52 @@ set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; SET SESSION DEFAULT_STORAGE_ENGINE=DEFAULT; SET GLOBAL innodb_stats_persistent=@save_stats_persistent; +# +# MDEV-30313 Sporadic assertion `cond_selectivity <= 1.0' failure in get_range_limit_read_cost +# +CREATE TABLE t (a CHAR(8), b INT, c TIMESTAMP, KEY(b,c)) ENGINE=InnoDB; +INSERT INTO t VALUES +('g',1,'1980-09-26'),('l',2,'1979-10-07'),('e',3,'1992-04-22'), +('v',9,'1975-09-21'),('w',3,'1973-10-06'),('y',8,'1986-10-28'), +('a',4,'2015-02-15'),('v',9,'1980-01-13'),('f',1,'1972-02-27'), +('z',7,'1981-05-25'),('z',8,'1980-06-14'),('c',9,'1985-01-24'), +('x',5,'1999-12-14'),('h',3,'1994-12-18'),('j',6,'1985-08-17'), +('b',6,'1989-08-02'),('h',6,'2024-07-06'),('h',4,'2024-02-10'), +('s',1,'1981-07-21'),('c',2,'1988-09-16'),('e',3,'1981-08-26'), +('a',2,'1986-05-23'),('l',0,'1997-12-19'),('b',5,'2018-05-01'), +('q',2,'1990-01-01'),('v',9,'1982-10-12'),('x',2,'2005-04-29'), +('f',8,'2005-08-20'),('d',3,'2002-01-24'),('b',9,'1982-02-04'), +('a',4,'1978-04-12'),('c',9,'1984-06-08'),('n',9,'1983-10-19'), +('l',1,'2023-01-05'),('f',2,'1988-11-18'),('a',9,'1977-11-11'), +('k',2,'1980-09-27'),('i',7,'1988-08-09'),('e',4,'1992-07-30'), +('l',5,'1980-01-01'),('h',5,'2011-12-24'),('d',6,'2035-03-28'), +('h',7,'1994-05-14'),('y',1,'1990-01-01'),('x',6,'1981-09-12'), +('x',9,'1980-01-01'),('s',9,'1995-11-09'),('i',4,'1980-01-01'), +('p',4,'1980-01-01'),('a',6,'2026-05-05'),('c',6,'1991-09-23'), +('l',8,'1980-01-01'),('n',4,'1999-09-15'),('b',1,'2011-07-23'), +('a',9,'1980-01-01'),('a',0,'1977-12-21'),('v',6,'1986-10-29'), +('r',0,'1997-03-27'),('a',9,'2000-05-05'),('x',1,'1990-01-01'), +('n',7,'1985-08-01'),('m',6,'1994-09-14'),('s',9,'2009-09-27'), +('r',8,'2028-10-30'),('e',6,'1982-08-31'),('x',0,'1989-12-21'), +('d',0,'1984-06-24'),('r',6,'1982-02-11'),('a',3,'1997-10-22'), +('s',9,'2007-08-29'),('a',3,'1990-01-01'),('o',1,'2015-02-10'), +('x',0,'1978-08-30'),('k',5,'1989-06-15'),('b',0,'1984-08-21'), +('v',0,'1990-01-01'),('a',9,'1993-06-23'),('n',5,'1979-11-10'), +('o',8,'2024-08-31'),('k',6,'1983-12-25'),('y',5,'2013-02-19'), +('a',9,'1989-12-03'),('k',4,'1973-08-07'),('o',7,'1988-03-19'), +('o',3,'2007-01-07'),('t',6,'1990-02-22'),('f',4,'2032-10-22'), +('p',0,'1977-09-12'),('f',3,'2036-11-26'),('a',9,'2008-06-26'), +('k',2,'2004-09-11'),('x',1,'2005-07-28'),('s',8,'2027-08-28'), +('a',8,'2000-06-11'),('a',7,'2005-05-20'),('u',9,'1980-01-01'), +('v',5,'1990-01-01'),('x',7,'1984-11-01'),('a',1,'2006-05-14'); +SELECT b FROM t WHERE a > 'a' GROUP BY b HAVING b >= 6 OR b <= 0; +b +0 +6 +7 +8 +9 +DROP TABLE t; +# +# End of 11.0 tests +# diff --git a/mysql-test/main/selectivity_innodb.test b/mysql-test/main/selectivity_innodb.test index c970e7d871d..dc06287a1f9 100644 --- a/mysql-test/main/selectivity_innodb.test +++ b/mysql-test/main/selectivity_innodb.test @@ -236,3 +236,52 @@ set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; SET SESSION DEFAULT_STORAGE_ENGINE=DEFAULT; SET GLOBAL innodb_stats_persistent=@save_stats_persistent; + +--echo # +--echo # MDEV-30313 Sporadic assertion `cond_selectivity <= 1.0' failure in get_range_limit_read_cost +--echo # + +CREATE TABLE t (a CHAR(8), b INT, c TIMESTAMP, KEY(b,c)) ENGINE=InnoDB; +INSERT INTO t VALUES +('g',1,'1980-09-26'),('l',2,'1979-10-07'),('e',3,'1992-04-22'), +('v',9,'1975-09-21'),('w',3,'1973-10-06'),('y',8,'1986-10-28'), +('a',4,'2015-02-15'),('v',9,'1980-01-13'),('f',1,'1972-02-27'), +('z',7,'1981-05-25'),('z',8,'1980-06-14'),('c',9,'1985-01-24'), +('x',5,'1999-12-14'),('h',3,'1994-12-18'),('j',6,'1985-08-17'), +('b',6,'1989-08-02'),('h',6,'2024-07-06'),('h',4,'2024-02-10'), +('s',1,'1981-07-21'),('c',2,'1988-09-16'),('e',3,'1981-08-26'), +('a',2,'1986-05-23'),('l',0,'1997-12-19'),('b',5,'2018-05-01'), +('q',2,'1990-01-01'),('v',9,'1982-10-12'),('x',2,'2005-04-29'), +('f',8,'2005-08-20'),('d',3,'2002-01-24'),('b',9,'1982-02-04'), +('a',4,'1978-04-12'),('c',9,'1984-06-08'),('n',9,'1983-10-19'), +('l',1,'2023-01-05'),('f',2,'1988-11-18'),('a',9,'1977-11-11'), +('k',2,'1980-09-27'),('i',7,'1988-08-09'),('e',4,'1992-07-30'), +('l',5,'1980-01-01'),('h',5,'2011-12-24'),('d',6,'2035-03-28'), +('h',7,'1994-05-14'),('y',1,'1990-01-01'),('x',6,'1981-09-12'), +('x',9,'1980-01-01'),('s',9,'1995-11-09'),('i',4,'1980-01-01'), +('p',4,'1980-01-01'),('a',6,'2026-05-05'),('c',6,'1991-09-23'), +('l',8,'1980-01-01'),('n',4,'1999-09-15'),('b',1,'2011-07-23'), +('a',9,'1980-01-01'),('a',0,'1977-12-21'),('v',6,'1986-10-29'), +('r',0,'1997-03-27'),('a',9,'2000-05-05'),('x',1,'1990-01-01'), +('n',7,'1985-08-01'),('m',6,'1994-09-14'),('s',9,'2009-09-27'), +('r',8,'2028-10-30'),('e',6,'1982-08-31'),('x',0,'1989-12-21'), +('d',0,'1984-06-24'),('r',6,'1982-02-11'),('a',3,'1997-10-22'), +('s',9,'2007-08-29'),('a',3,'1990-01-01'),('o',1,'2015-02-10'), +('x',0,'1978-08-30'),('k',5,'1989-06-15'),('b',0,'1984-08-21'), +('v',0,'1990-01-01'),('a',9,'1993-06-23'),('n',5,'1979-11-10'), +('o',8,'2024-08-31'),('k',6,'1983-12-25'),('y',5,'2013-02-19'), +('a',9,'1989-12-03'),('k',4,'1973-08-07'),('o',7,'1988-03-19'), +('o',3,'2007-01-07'),('t',6,'1990-02-22'),('f',4,'2032-10-22'), +('p',0,'1977-09-12'),('f',3,'2036-11-26'),('a',9,'2008-06-26'), +('k',2,'2004-09-11'),('x',1,'2005-07-28'),('s',8,'2027-08-28'), +('a',8,'2000-06-11'),('a',7,'2005-05-20'),('u',9,'1980-01-01'), +('v',5,'1990-01-01'),('x',7,'1984-11-01'),('a',1,'2006-05-14'); + +SELECT b FROM t WHERE a > 'a' GROUP BY b HAVING b >= 6 OR b <= 0; + +# Cleanup +DROP TABLE t; + +--echo # +--echo # End of 11.0 tests +--echo # diff --git a/mysql-test/main/selectivity_no_engine.result b/mysql-test/main/selectivity_no_engine.result index 3811b12a1be..5df1c61e758 100644 --- a/mysql-test/main/selectivity_no_engine.result +++ b/mysql-test/main/selectivity_no_engine.result @@ -314,6 +314,25 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE a ALL NULL NULL NULL NULL 5 Using where 1 SIMPLE b hash_ALL NULL #hash#$hj 1341 test.a.Host,test.a.User,test.a.Password,test.a.Select_priv,test.a.Insert_priv,test.a.Update_priv,test.a.Delete_priv,test.a.Create_priv,test.a.Drop_priv,test.a.Reload_priv,test.a.Shutdown_priv,test.a.Process_priv,test.a.File_priv,test.a.Grant_priv,test.a.References_priv,test.a.Index_priv,test.a.Alter_priv,test.a.Show_db_priv,test.a.Super_priv,test.a.Create_tmp_table_priv,test.a.Lock_tables_priv,test.a.Execute_priv,test.a.Repl_slave_priv,test.a.Repl_client_priv,test.a.Create_view_priv,test.a.Show_view_priv,test.a.Create_routine_priv,test.a.Alter_routine_priv,test.a.Create_user_priv,test.a.Event_priv,test.a.Trigger_priv,test.a.Create_tablespace_priv,test.a.Delete_history_priv,test.a.ssl_type,test.a.ssl_cipher,test.a.x509_issuer,test.a.x509_subject,test.a.max_questions,test.a.max_updates,test.a.max_connections,test.a.max_user_connections,test.a.plugin,test.a.authentication_string,test.a.password_expired,test.a.is_role,test.a.default_role,test.a.max_statement_time 5 Using where; Using join buffer (flat, BNLH join) DROP TABLE t1,t2,t3; +# +# MDEV-30529: Assertion `rnd_records <= s->found_records' failed in best_access_path +# +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b VARCHAR(1), c INT, d VARCHAR(1), e VARCHAR(1), KEY(b), KEY(d), KEY(e)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('x',0,'-','-'), +('x',0,'-','-'),('x',5,'-','-'),('x',0,'-','-'),('x',0,'-','-'), +('x',0,'-','-'),('x',0,'w','-'),('x',0,'-','-'),('x',0,'-','-'), +('x',0,'-','-'),('x',0,'-','-'),('x',0,'-','u'),('x',0,'-','-'), +('x',0,'-','-'),('x',0,'-','t'),('x',0,'-','-'),('x',0,'-','-'), +('x',0,'-','-'),('x',0,'-','-'),('x',0,'-','-'),('x',0,'-','p'), +('x',0,'z','-'),('x',0,'-','-'),('x',0,'-','-'),('x',0,'-','v'); +set @tmp_jcl=@@join_cache_level; +SET JOIN_CACHE_LEVEL= 3; +SELECT * FROM t1 JOIN t2 ON t1.a = t2.c WHERE t2.b IN ('o') OR t2.e >= 'f' OR t2.d > 'p'; +a b c d e +set join_cache_level=@tmp_jcl; +drop table t1,t2; # # End of the test file # diff --git a/mysql-test/main/selectivity_no_engine.test b/mysql-test/main/selectivity_no_engine.test index 5bc78e03781..8596fce9bf2 100644 --- a/mysql-test/main/selectivity_no_engine.test +++ b/mysql-test/main/selectivity_no_engine.test @@ -250,6 +250,27 @@ SELECT * FROM t1 AS a NATURAL JOIN t1 AS b; DROP TABLE t1,t2,t3; +--echo # +--echo # MDEV-30529: Assertion `rnd_records <= s->found_records' failed in best_access_path +--echo # +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (b VARCHAR(1), c INT, d VARCHAR(1), e VARCHAR(1), KEY(b), KEY(d), KEY(e)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('x',0,'-','-'), +('x',0,'-','-'),('x',5,'-','-'),('x',0,'-','-'),('x',0,'-','-'), +('x',0,'-','-'),('x',0,'w','-'),('x',0,'-','-'),('x',0,'-','-'), +('x',0,'-','-'),('x',0,'-','-'),('x',0,'-','u'),('x',0,'-','-'), +('x',0,'-','-'),('x',0,'-','t'),('x',0,'-','-'),('x',0,'-','-'), +('x',0,'-','-'),('x',0,'-','-'),('x',0,'-','-'),('x',0,'-','p'), +('x',0,'z','-'),('x',0,'-','-'),('x',0,'-','-'),('x',0,'-','v'); + +set @tmp_jcl=@@join_cache_level; +SET JOIN_CACHE_LEVEL= 3; +SELECT * FROM t1 JOIN t2 ON t1.a = t2.c WHERE t2.b IN ('o') OR t2.e >= 'f' OR t2.d > 'p'; +set join_cache_level=@tmp_jcl; + +drop table t1,t2; --echo # --echo # End of the test file --echo # diff --git a/mysql-test/main/set_operation.result b/mysql-test/main/set_operation.result index fa0fe21d156..f01b68357a2 100644 --- a/mysql-test/main/set_operation.result +++ b/mysql-test/main/set_operation.result @@ -221,7 +221,7 @@ NULL UNIT RESULT ALL NULL NULL NULL NULL NULL NULL 16 EXCEPT NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNIT RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 /* select#1 */ select `__14`.`1` AS `1` from (/* select#8 */ select `__7`.`1` AS `1` from (/* select#2 */ select 1 AS `1` except /* select#3 */ select 5 AS `5` union /* select#4 */ select 6 AS `6`) `__7` union /* select#9 */ select `__8`.`2` AS `2` from (/* select#5 */ select 2 AS `2` intersect /* select#6 */ select 3 AS `3` intersect /* select#7 */ select 4 AS `4`) `__8` except /* select#12 */ select `__11`.`7` AS `7` from (/* select#10 */ select 7 AS `7` intersect /* select#11 */ select 8 AS `8`) `__11`) `__14` union all /* select#15 */ select `__15`.`9` AS `9` from (/* select#13 */ select 9 AS `9` union all /* select#14 */ select 10 AS `10`) `__15` except all /* select#16 */ select 11 AS `11` +Note 1003 /* select#1 */ select `__14`.`1` AS `1` from (/* select#8 */ select `__7`.`1` AS `1` from (/* select#2 */ select 1 AS `1` except /* select#3 */ select 5 AS `5` union all /* select#4 */ select 6 AS `6`) `__7` union /* select#9 */ select `__8`.`2` AS `2` from (/* select#5 */ select 2 AS `2` intersect /* select#6 */ select 3 AS `3` intersect /* select#7 */ select 4 AS `4`) `__8` except /* select#12 */ select `__11`.`7` AS `7` from (/* select#10 */ select 7 AS `7` intersect /* select#11 */ select 8 AS `8`) `__11`) `__14` union all /* select#15 */ select `__15`.`9` AS `9` from (/* select#13 */ select 9 AS `9` union all /* select#14 */ select 10 AS `10`) `__15` except all /* select#16 */ select 11 AS `11` (select 1 union all select 2) union (select 3 union all select 4); @@ -242,7 +242,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 5 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 /* select#1 */ select `__5`.`1` AS `1` from (/* select#2 */ select 1 AS `1` union /* select#3 */ select 2 AS `2`) `__5` union /* select#6 */ select `__6`.`3` AS `3` from (/* select#4 */ select 3 AS `3` union /* select#5 */ select 4 AS `4`) `__6` +Note 1003 /* select#1 */ select `__5`.`1` AS `1` from (/* select#2 */ select 1 AS `1` union all /* select#3 */ select 2 AS `2`) `__5` union /* select#6 */ select `__6`.`3` AS `3` from (/* select#4 */ select 3 AS `3` union /* select#5 */ select 4 AS `4`) `__6` (select 1 intersect all select 2) except select 3; @@ -258,7 +258,7 @@ NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL NULL 4 EXCEPT NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 /* select#1 */ select `__4`.`1` AS `1` from (/* select#2 */ select 1 AS `1` intersect /* select#3 */ select 2 AS `2`) `__4` except /* select#4 */ select 3 AS `3` +Note 1003 /* select#1 */ select `__4`.`1` AS `1` from (/* select#2 */ select 1 AS `1` intersect all /* select#3 */ select 2 AS `2`) `__4` except /* select#4 */ select 3 AS `3` (select 1 intersect all select 2 intersect all select 3) intersect (select 4 intersect all select 5); @@ -278,7 +278,7 @@ NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL NULL NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL NULL NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 /* select#1 */ select `__6`.`1` AS `1` from (/* select#2 */ select 1 AS `1` intersect /* select#3 */ select 2 AS `2` intersect /* select#4 */ select 3 AS `3`) `__6` intersect /* select#7 */ select `__7`.`4` AS `4` from (/* select#5 */ select 4 AS `4` intersect /* select#6 */ select 5 AS `5`) `__7` +Note 1003 /* select#1 */ select `__6`.`1` AS `1` from (/* select#2 */ select 1 AS `1` intersect all /* select#3 */ select 2 AS `2` intersect all /* select#4 */ select 3 AS `3`) `__6` intersect /* select#7 */ select `__7`.`4` AS `4` from (/* select#5 */ select 4 AS `4` intersect /* select#6 */ select 5 AS `5`) `__7` # test set operations with table value constructor (values (1,1),(1,1),(1,1),(2,2),(2,2),(3,3),(9,9)) INTERSECT ALL @@ -571,12 +571,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100 } } @@ -587,12 +590,15 @@ EXPLAIN "query_block": { "select_id": 8, "operation": "UNION", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -603,12 +609,15 @@ EXPLAIN { "query_block": { "select_id": 2, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 6, + "cost": "REPLACED", "filtered": 100 } } @@ -628,12 +637,15 @@ EXPLAIN "query_block": { "select_id": 4, "operation": "INTERSECT", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -642,12 +654,15 @@ EXPLAIN { "query_block": { "select_id": 5, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100 } } @@ -658,12 +673,15 @@ EXPLAIN "query_block": { "select_id": 6, "operation": "UNION", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100 } } @@ -692,12 +710,15 @@ EXPLAIN "query_block": { "select_id": 7, "operation": "EXCEPT", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100 } } @@ -708,12 +729,15 @@ EXPLAIN "query_block": { "select_id": 9, "operation": "UNION", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 6, + "cost": "REPLACED", "filtered": 100 } } @@ -724,12 +748,15 @@ EXPLAIN "query_block": { "select_id": 10, "operation": "UNION", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100 } } @@ -740,12 +767,15 @@ EXPLAIN "query_block": { "select_id": 11, "operation": "EXCEPT", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100 } }, @@ -754,7 +784,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 5, "rows": 6, + "cost": "REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -769,12 +801,15 @@ EXPLAIN "query_block": { "select_id": 12, "operation": "UNION", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100, "attached_condition": "t1.a < 4" } @@ -784,7 +819,9 @@ EXPLAIN "table": { "table_name": "t2", "access_type": "ALL", + "loops": 5, "rows": 6, + "cost": "REPLACED", "filtered": 100 }, "buffer_type": "flat", @@ -799,12 +836,15 @@ EXPLAIN "query_block": { "select_id": 13, "operation": "UNION", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 5, + "cost": "REPLACED", "filtered": 100 } } diff --git a/mysql-test/main/set_operation.test b/mysql-test/main/set_operation.test index c422042f371..e9f71a7e448 100644 --- a/mysql-test/main/set_operation.test +++ b/mysql-test/main/set_operation.test @@ -272,6 +272,7 @@ select * from v0 where g < 4 UNION ALL select * from t3; +--source include/analyze-format.inc EXPLAIN format=json select * from t1 UNION ALL diff --git a/mysql-test/main/show_analyze.result b/mysql-test/main/show_analyze.result index 5595fadd60b..2cc18e40d94 100644 --- a/mysql-test/main/show_analyze.result +++ b/mysql-test/main/show_analyze.result @@ -405,6 +405,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "filesort": { @@ -421,9 +422,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, diff --git a/mysql-test/main/show_analyze_json.result b/mysql-test/main/show_analyze_json.result index 8506c4b9402..87f2ea9a655 100644 --- a/mysql-test/main/show_analyze_json.result +++ b/mysql-test/main/show_analyze_json.result @@ -44,15 +44,18 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 1000, "r_rows": 1000, + "cost": "REPLACED", "filtered": 50, "r_filtered": 50, "attached_condition": "t1.c < 500" @@ -77,15 +80,18 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 1000, "r_rows": 1000, + "cost": "REPLACED", "filtered": 10, "r_filtered": 10, "attached_condition": "t1.c < 10" @@ -111,6 +117,7 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -119,9 +126,11 @@ SHOW ANALYZE "table_name": "t1", "access_type": "ALL", "possible_keys": ["a"], + "loops": 1, "r_loops": 1, "rows": 1000, "r_rows": 1000, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 99.90000153, @@ -160,15 +169,18 @@ SHOW ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 60, "attached_condition": "a.a <= 5" @@ -181,14 +193,17 @@ SHOW ANALYZE "query_block": { "select_id": 2, "operation": "UNION", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 10, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null, "attached_condition": "b.a >= 9" @@ -229,15 +244,18 @@ SHOW ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 60, "attached_condition": "a.a <= 5" @@ -250,15 +268,18 @@ SHOW ANALYZE "query_block": { "select_id": 2, "operation": "UNION", + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 10, "attached_condition": "b.a >= 9" @@ -299,6 +320,7 @@ SHOW ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -306,9 +328,11 @@ SHOW ANALYZE "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -323,14 +347,17 @@ SHOW ANALYZE "query_block": { "select_id": 2, "operation": "UNION", + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 10, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null, "attached_condition": "b.a >= 9" @@ -371,6 +398,7 @@ SHOW ANALYZE { "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -378,9 +406,11 @@ SHOW ANALYZE "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -395,6 +425,7 @@ SHOW ANALYZE "query_block": { "select_id": 2, "operation": "UNION", + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -402,9 +433,11 @@ SHOW ANALYZE "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -441,15 +474,18 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 20, "attached_condition": "a.a < 2" @@ -460,15 +496,18 @@ SHOW ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 30, "attached_condition": "b.a > 6" @@ -501,6 +540,7 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -508,9 +548,11 @@ SHOW ANALYZE "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -523,6 +565,7 @@ SHOW ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -530,9 +573,11 @@ SHOW ANALYZE "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -567,14 +612,17 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 10, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null, "attached_condition": "a.a < 2" @@ -588,14 +636,17 @@ SHOW ANALYZE "r_loops": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 10, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null, "attached_condition": "b.a + a.a < 10" @@ -629,15 +680,18 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 20, "attached_condition": "a.a < 2" @@ -651,15 +705,18 @@ SHOW ANALYZE "r_hit_ratio": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 2, "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 2, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 95, "attached_condition": "b.a + a.a < 10" @@ -693,6 +750,7 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -700,9 +758,11 @@ SHOW ANALYZE "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -718,6 +778,7 @@ SHOW ANALYZE "r_hit_ratio": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 2, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -725,9 +786,11 @@ SHOW ANALYZE "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "r_loops": 2, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -791,14 +854,17 @@ SHOW ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 10, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null, "attached_condition": "t2.a + t0.a < 3" @@ -834,15 +900,18 @@ SHOW ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 30, "attached_condition": "t2.a + t0.a < 3" @@ -889,14 +958,17 @@ SHOW ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 10, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null, "attached_condition": "t2.a + t0.a < 3" @@ -932,15 +1004,18 @@ SHOW ANALYZE { "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 30, "attached_condition": "t2.a + t0.a < 3" @@ -974,15 +1049,18 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 1, + "cost": "REPLACED", "filtered": 100, "r_filtered": 100 } @@ -995,14 +1073,17 @@ SHOW ANALYZE "r_hit_ratio": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 0, "rows": 10, "r_rows": null, + "cost": "REPLACED", "filtered": 100, "r_filtered": null, "attached_condition": "t2.a + t0.a < 3" @@ -1026,15 +1107,18 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 2, + "cost": "REPLACED", "filtered": 100, "r_filtered": 100 } @@ -1047,15 +1131,18 @@ SHOW ANALYZE "r_hit_ratio": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 30, "attached_condition": "t2.a + t0.a < 3" @@ -1079,15 +1166,18 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "filtered": 100, "r_filtered": 100 } @@ -1100,15 +1190,18 @@ SHOW ANALYZE "r_hit_ratio": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 2, "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 2, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 25, "attached_condition": "t2.a + t0.a < 3" @@ -1146,6 +1239,7 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "nested_loop": [ { @@ -1161,9 +1255,11 @@ SHOW ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 100 } @@ -1205,6 +1301,7 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "temporary_table": { "nested_loop": [ @@ -1212,9 +1309,11 @@ SHOW ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 100 } @@ -1254,6 +1353,7 @@ SHOW ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "temporary_table": { "nested_loop": [ @@ -1261,9 +1361,11 @@ SHOW ANALYZE "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "filtered": 100, "r_filtered": 100 } diff --git a/mysql-test/main/show_explain.result b/mysql-test/main/show_explain.result index 6bdc773aa4c..20333c925d4 100644 --- a/mysql-test/main/show_explain.result +++ b/mysql-test/main/show_explain.result @@ -730,8 +730,8 @@ SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`) connection default; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 20 1 PRIMARY const distinct_key distinct_key 8 const,const 1 -1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) 2 MATERIALIZED t2 index NULL a1 4 NULL 20 Using index Warnings: Note 1003 SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`) @@ -1264,7 +1264,7 @@ explain SELECT b AS field1, b AS field2 FROM t1, t2, t3 WHERE d = b ORDER BY field1, field2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 system NULL NULL NULL NULL 1 -1 SIMPLE t1 range b b 6 NULL 107 Using where; Using index +1 SIMPLE t1 index b b 6 NULL 107 Using where; Using index 1 SIMPLE t3 ref PRIMARY PRIMARY 5 test.t1.b 1 Using index set @show_explain_probe_select_id=1; SET debug_dbug='+d,show_explain_probe_do_select'; @@ -1273,7 +1273,7 @@ connection default; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 system NULL NULL NULL NULL 1 -1 SIMPLE t1 range b b 6 NULL 107 Using where; Using index +1 SIMPLE t1 index b b 6 NULL 107 Using where; Using index 1 SIMPLE t3 ref PRIMARY PRIMARY 5 test.t1.b 1 Using index Warnings: Note 1003 SELECT b AS field1, b AS field2 FROM t1, t2, t3 WHERE d = b ORDER BY field1, field2 diff --git a/mysql-test/main/show_explain_json.result b/mysql-test/main/show_explain_json.result index a5c441af5b8..4a21528e41d 100644 --- a/mysql-test/main/show_explain_json.result +++ b/mysql-test/main/show_explain_json.result @@ -47,6 +47,7 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -56,7 +57,9 @@ SHOW EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 999, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.a < 100000", "using_index": true @@ -77,6 +80,7 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -86,7 +90,9 @@ SHOW EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a < 10" } @@ -106,6 +112,7 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -115,7 +122,9 @@ SHOW EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a < 10" } @@ -138,6 +147,7 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -147,7 +157,9 @@ SHOW EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a < 10", "mrr_type": "Rowid-ordered scan" @@ -169,6 +181,7 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -178,7 +191,9 @@ SHOW EXPLAIN "key": "a", "key_length": "5", "used_key_parts": ["a"], + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t1.a < 10", "mrr_type": "Rowid-ordered scan" @@ -210,12 +225,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "A", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -226,12 +244,15 @@ SHOW EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "B", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -266,12 +287,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "A", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -282,12 +306,15 @@ SHOW EXPLAIN "query_block": { "select_id": 2, "operation": "UNION", + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "B", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -378,12 +405,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "a.a < 1" } @@ -394,12 +424,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "b.a + a.a < 10" } @@ -427,12 +460,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "a.a < 1" } @@ -443,12 +479,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "b.a + a.a < 10" } @@ -476,12 +515,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "a", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "a.a < 1" } @@ -492,12 +534,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "b", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "b.a + a.a < 10" } @@ -552,12 +597,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -586,12 +634,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -628,12 +679,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -662,12 +716,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -707,12 +764,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -741,12 +801,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -786,12 +849,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -820,12 +886,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -854,12 +923,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -869,12 +941,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -893,12 +968,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -908,12 +986,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -932,12 +1013,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -947,12 +1031,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -986,12 +1073,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1001,12 +1091,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -1025,12 +1118,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1040,12 +1136,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -1064,12 +1163,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1079,12 +1181,15 @@ SHOW EXPLAIN "expression_cache": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t2.a + t0.a < 3" } @@ -1120,6 +1225,7 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "read_sorted_file": { @@ -1128,7 +1234,9 @@ SHOW EXPLAIN "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1169,13 +1277,16 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1215,13 +1326,16 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "temporary_table": { "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1264,12 +1378,15 @@ SHOW EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t0.a = (octet_length('гы'))" } diff --git a/mysql-test/main/show_explain_json.test b/mysql-test/main/show_explain_json.test index 8d2a6aa82bb..321fa46be87 100644 --- a/mysql-test/main/show_explain_json.test +++ b/mysql-test/main/show_explain_json.test @@ -118,6 +118,7 @@ send select count(*) from t1 where a < 100000; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain FORMAT=JSON for $thr2; connection con1; reap; @@ -126,6 +127,7 @@ reap; send select max(c) from t1 where a < 10; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain FORMAT=JSON for connection $thr2; connection con1; reap; @@ -134,6 +136,7 @@ reap; send select max(c) from t1 where a < 10; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; connection con1; reap; @@ -145,6 +148,7 @@ set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_sort_keys=on'; send explain select max(c) from t1 where a < 10; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=json for $thr2; connection con1; reap; @@ -153,6 +157,7 @@ reap; send explain select max(c) from t1 where a < 10; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; connection con1; reap; @@ -165,6 +170,7 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send explain select a from t0 A union select a+1 from t0 B; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format = JSON for $thr2; connection con1; reap; @@ -177,6 +183,7 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send explain select a from t0 A union select a+1 from t0 B; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; connection con1; reap; @@ -234,6 +241,7 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; connection con1; reap; @@ -245,6 +253,7 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; connection con1; reap; @@ -256,6 +265,7 @@ SET debug_dbug='+d,show_explain_probe_join_exec_end'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; connection con1; reap; @@ -293,8 +303,10 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; connection con1; reap; @@ -308,8 +320,10 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; connection con1; reap; @@ -326,8 +340,10 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; connection con1; reap; @@ -343,8 +359,10 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; connection con1; reap; @@ -360,10 +378,13 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=json for $thr2; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=json for $thr2; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=json for $thr2; connection con1; reap; @@ -380,10 +401,13 @@ SET debug_dbug='+d,show_explain_probe_join_exec_start'; send select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp explain format=JSON for connection $thr2; connection con1; reap; @@ -400,6 +424,7 @@ set @show_explain_probe_select_id=1; send select * from t0 order by a; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=json for $thr2; connection con1; reap; @@ -417,6 +442,7 @@ set @show_explain_probe_select_id=1; send select distinct a from t0; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=json for $thr2; connection con1; reap; @@ -435,6 +461,7 @@ set @show_explain_probe_select_id=1; send select distinct a from t0; connection default; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=json for $thr2; connection con1; reap; @@ -461,6 +488,7 @@ select * from t0 where length(' connection default; set names utf8; --source include/wait_condition.inc +--source include/explain-no-costs.inc evalp show explain format=JSON for $thr2; set names default; diff --git a/mysql-test/main/signal_demo1.result b/mysql-test/main/signal_demo1.result index d919f48404f..752f23a48d6 100644 --- a/mysql-test/main/signal_demo1.result +++ b/mysql-test/main/signal_demo1.result @@ -75,9 +75,6 @@ end; end case; end $$ -Warnings: -Warning 1287 ' INTO FROM...' instead -Warning 1287 ' INTO FROM...' instead create procedure check_pk_inventory(in id integer) begin declare x integer; @@ -95,8 +92,6 @@ MYSQL_ERRNO = 10000; end if; end $$ -Warnings: -Warning 1287 ' INTO FROM...' instead create procedure check_pk_order(in id integer) begin declare x integer; @@ -113,8 +108,6 @@ MYSQL_ERRNO = 10000; end if; end $$ -Warnings: -Warning 1287 ' INTO FROM...' instead create trigger po_order_bi before insert on po_order for each row begin diff --git a/mysql-test/main/single_delete_update.result b/mysql-test/main/single_delete_update.result index 85e79f53c89..6a17895ef8a 100644 --- a/mysql-test/main/single_delete_update.result +++ b/mysql-test/main/single_delete_update.result @@ -129,21 +129,21 @@ a b c d SHOW SESSION STATUS LIKE 'Sort%'; Variable_name Value Sort_merge_passes 0 -Sort_priority_queue_sorts 1 +Sort_priority_queue_sorts 0 Sort_range 0 -Sort_rows 1 -Sort_scan 1 +Sort_rows 0 +Sort_scan 0 SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value -Handler_read_first 0 +Handler_read_first 1 Handler_read_key 0 Handler_read_last 0 -Handler_read_next 0 +Handler_read_next 16 Handler_read_prev 0 Handler_read_retry 0 Handler_read_rnd 0 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 17 +Handler_read_rnd_next 0 FLUSH STATUS; DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; SHOW SESSION STATUS LIKE 'Sort%'; @@ -151,19 +151,19 @@ Variable_name Value Sort_merge_passes 0 Sort_priority_queue_sorts 0 Sort_range 0 -Sort_rows 1 -Sort_scan 1 +Sort_rows 0 +Sort_scan 0 SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value -Handler_read_first 0 +Handler_read_first 1 Handler_read_key 0 Handler_read_last 0 -Handler_read_next 0 +Handler_read_next 16 Handler_read_prev 0 Handler_read_retry 0 -Handler_read_rnd 1 +Handler_read_rnd 0 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 17 +Handler_read_rnd_next 0 ## should be 5 (previous LIMIT) SELECT 1 - COUNT(*) FROM t2 WHERE b = 10; 1 - COUNT(*) @@ -332,6 +332,7 @@ DROP TABLE t2; # CREATE TABLE t2 (i INT, key1 INT, key2 INT, INDEX (key1), INDEX (key2)); INSERT INTO t2 (key1, key2) SELECT i, i FROM t1; +INSERT INTO t2 (key1, key2) SELECT i+100, i+100 FROM t1; FLUSH STATUS; SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; i key1 key2 @@ -734,41 +735,41 @@ a b c d SHOW SESSION STATUS LIKE 'Sort%'; Variable_name Value Sort_merge_passes 0 -Sort_priority_queue_sorts 1 +Sort_priority_queue_sorts 0 Sort_range 0 -Sort_rows 1 -Sort_scan 1 +Sort_rows 0 +Sort_scan 0 SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value -Handler_read_first 0 +Handler_read_first 1 Handler_read_key 0 Handler_read_last 0 -Handler_read_next 0 +Handler_read_next 16 Handler_read_prev 0 Handler_read_retry 0 Handler_read_rnd 0 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 17 +Handler_read_rnd_next 0 FLUSH STATUS; UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; SHOW SESSION STATUS LIKE 'Sort%'; Variable_name Value Sort_merge_passes 0 -Sort_priority_queue_sorts 1 +Sort_priority_queue_sorts 0 Sort_range 0 -Sort_rows 1 -Sort_scan 1 +Sort_rows 0 +Sort_scan 0 SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value -Handler_read_first 0 +Handler_read_first 1 Handler_read_key 0 Handler_read_last 0 -Handler_read_next 0 +Handler_read_next 16 Handler_read_prev 0 Handler_read_retry 0 Handler_read_rnd 1 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 17 +Handler_read_rnd_next 0 ## should be 5 (previous LIMIT) SELECT COUNT(*) FROM t2 WHERE b = 10 AND d = 10 ORDER BY a, c; COUNT(*) @@ -939,6 +940,7 @@ DROP TABLE t2; # CREATE TABLE t2 (i INT, key1 INT, key2 INT, INDEX (key1), INDEX (key2)); INSERT INTO t2 (key1, key2) SELECT i, i FROM t1; +INSERT INTO t2 (key1, key2) SELECT i+100, i+100 FROM t1; FLUSH STATUS; SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; i key1 key2 diff --git a/mysql-test/main/single_delete_update.test b/mysql-test/main/single_delete_update.test index 4a4ad5e5a8e..05cff5e1413 100644 --- a/mysql-test/main/single_delete_update.test +++ b/mysql-test/main/single_delete_update.test @@ -147,6 +147,7 @@ DROP TABLE t2; CREATE TABLE t2 (i INT, key1 INT, key2 INT, INDEX (key1), INDEX (key2)); INSERT INTO t2 (key1, key2) SELECT i, i FROM t1; +INSERT INTO t2 (key1, key2) SELECT i+100, i+100 FROM t1; FLUSH STATUS; SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; @@ -372,6 +373,7 @@ DROP TABLE t2; CREATE TABLE t2 (i INT, key1 INT, key2 INT, INDEX (key1), INDEX (key2)); INSERT INTO t2 (key1, key2) SELECT i, i FROM t1; +INSERT INTO t2 (key1, key2) SELECT i+100, i+100 FROM t1; FLUSH STATUS; SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; diff --git a/mysql-test/main/sp-anchor-row-type-cursor.result b/mysql-test/main/sp-anchor-row-type-cursor.result index e56c51bb82e..e3c6e1fc167 100644 --- a/mysql-test/main/sp-anchor-row-type-cursor.result +++ b/mysql-test/main/sp-anchor-row-type-cursor.result @@ -936,8 +936,6 @@ SELECT rec1.a, rec1.b; END; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: The used SELECT statements have a different number of columns DROP TABLE t1; @@ -957,8 +955,6 @@ SELECT rec1.a, rec1.b; END; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: Operand should contain 2 column(s) DROP TABLE t1; @@ -976,8 +972,6 @@ SELECT rec1.a, rec1.b; END; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); rec1.a rec1.b 10 b10 diff --git a/mysql-test/main/sp-anchor-row-type-table.result b/mysql-test/main/sp-anchor-row-type-table.result index 00fda5f12ad..c1b45c4e7d1 100644 --- a/mysql-test/main/sp-anchor-row-type-table.result +++ b/mysql-test/main/sp-anchor-row-type-table.result @@ -606,8 +606,6 @@ SELECT 10,'a','b' FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: The used SELECT statements have a different number of columns DROP TABLE t1; @@ -624,8 +622,6 @@ SELECT 10,'a' FROM t1 INTO rec1, rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: Operand should contain 2 column(s) DROP TABLE t1; @@ -642,8 +638,6 @@ SELECT * FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); rec1.a rec1.b 10 b10 diff --git a/mysql-test/main/sp-anchor-type.result b/mysql-test/main/sp-anchor-type.result index 47bbed31e19..31c8ff7469b 100644 --- a/mysql-test/main/sp-anchor-type.result +++ b/mysql-test/main/sp-anchor-type.result @@ -957,8 +957,6 @@ SELECT * FROM t1 INTO v_a, v_b, v_c; SELECT v_a, v_b, v_c; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); v_a v_b v_c 1 b1 2001-01-01 10:20:30.123 diff --git a/mysql-test/main/sp-big.result b/mysql-test/main/sp-big.result index ea93f2cac60..611ac9b74e9 100644 --- a/mysql-test/main/sp-big.result +++ b/mysql-test/main/sp-big.result @@ -77,8 +77,6 @@ select count(*) as cnt from (select id1 from t1 force index (primary) where id1 set id1_cond = id1_cond + 1; end while; end// -Warnings: -Warning 1287 ' INTO FROM...' instead insert t1 select seq, seq, 1, 1, seq, seq, seq from seq_1_to_2000; set @before=unix_timestamp(); call select_test(); diff --git a/mysql-test/main/sp-error.result b/mysql-test/main/sp-error.result index c77f58b6a66..f4928d16f55 100644 --- a/mysql-test/main/sp-error.result +++ b/mysql-test/main/sp-error.result @@ -1,7 +1,5 @@ drop table if exists t1, t2; SELECT * FROM mysql.proc INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/proc.txt'; -Warnings: -Warning 1287 ' INTO FROM...' instead delete from mysql.proc; create procedure syntaxerror(t int)| ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 @@ -14,8 +12,6 @@ create table t3 ( x int )| insert into t3 values (2), (3)| create procedure bad_into(out param int) select x from t3 into param| -Warnings: -Warning 1287 ' INTO FROM...' instead call bad_into(@x)| ERROR 42000: Result consisted of more than one row drop procedure bad_into| @@ -2842,8 +2838,6 @@ DECLARE v VARCHAR(5) DEFAULT -1; SELECT b FROM t1 WHERE a = 2 INTO v; RETURN v; END| -Warnings: -Warning 1287 ' INTO FROM...' instead # Here we check that the NOT_FOUND condition raised in f1() # is not visible in the outer function (f2), i.e. the continue diff --git a/mysql-test/main/sp-row.result b/mysql-test/main/sp-row.result index b66455dfdb9..a47f124f9a7 100644 --- a/mysql-test/main/sp-row.result +++ b/mysql-test/main/sp-row.result @@ -2136,8 +2136,6 @@ SELECT * FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: The used SELECT statements have a different number of columns DROP TABLE t1; @@ -2152,8 +2150,6 @@ SELECT * FROM t1 INTO rec1, rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: Operand should contain 2 column(s) DROP TABLE t1; @@ -2168,8 +2164,6 @@ SELECT * FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); rec1.a rec1.b 10 b10 diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 37c22e45b45..1204a905a73 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -320,8 +320,6 @@ repeat(select 1) into outfile 'b2'; insert into test.t1 values (repeat("b2",3), x); set x = x-1; until x = 0 end repeat| -Warnings: -Warning 1287 ' INTO FROM...' instead drop procedure b2| drop procedure if exists c| create procedure c(x int) @@ -4283,9 +4281,6 @@ select i as 'A local variable in a nested compound statement takes precedence o end; end; end| -Warnings: -Warning 1287 ' INTO FROM...' instead -Warning 1287 ' INTO FROM...' instead call bug5967("a - stored procedure parameter")| a a - stored procedure parameter @@ -5779,8 +5774,6 @@ end; select 1 from no_such_view limit 1 into x; return x; end| -Warnings: -Warning 1287 ' INTO FROM...' instead create function func_8407_b() returns int begin declare x int default 0; diff --git a/mysql-test/main/sp_trans.result b/mysql-test/main/sp_trans.result index d558442a6e7..10256bf4cb2 100644 --- a/mysql-test/main/sp_trans.result +++ b/mysql-test/main/sp_trans.result @@ -506,8 +506,6 @@ insert into t3 select a from t3; select count(*)*255 from t3 into table_size; until table_size > max_table_size*2 end repeat; end| -Warnings: -Warning 1287 ' INTO FROM...' instead call bug14210_fill_table()| drop procedure bug14210_fill_table| create table t4 like t3| diff --git a/mysql-test/main/sp_trans_log.result b/mysql-test/main/sp_trans_log.result index adc9eafc370..b72e8332fad 100644 --- a/mysql-test/main/sp_trans_log.result +++ b/mysql-test/main/sp_trans_log.result @@ -11,8 +11,6 @@ insert into t1 values (null); select count(*) from t1 into @a; return @a; end| -Warnings: -Warning 1287 ' INTO FROM...' instead reset master; insert into t2 values (bug23333(),1); ERROR 23000: Duplicate entry '1' for key 'PRIMARY' diff --git a/mysql-test/main/sql_safe_updates.result b/mysql-test/main/sql_safe_updates.result index f2944e60489..099aaa9bca6 100644 --- a/mysql-test/main/sql_safe_updates.result +++ b/mysql-test/main/sql_safe_updates.result @@ -9,18 +9,23 @@ select @@sql_safe_updates; # create table t1 (a int, b int, primary key (a), key (b)); update t1 set b=2 where a=1 or b=2; -ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column explain update t1 set b=2 where a=1 or b=2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t1 where a=1 or b=2; -ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column explain delete from t1 where a=1 or b=2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8); +explain update t1 set b=2 where a=1 or b=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge PRIMARY,b PRIMARY,b 4,5 NULL 2 Using union(PRIMARY,b); Using where; Using buffer update t1 set b=2 where a=1 or b=2; +set @@optimizer_switch="index_merge=off"; +update t1 set b=2 where a=1 or b=2; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column delete from t1 where a=1 or b=2; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column drop table t1; # # End of 10.3 tests diff --git a/mysql-test/main/sql_safe_updates.test b/mysql-test/main/sql_safe_updates.test index 25fe4a15ca2..becabb6881e 100644 --- a/mysql-test/main/sql_safe_updates.test +++ b/mysql-test/main/sql_safe_updates.test @@ -7,14 +7,17 @@ select @@sql_safe_updates; --echo # MDEV-18304 sql_safe_updates does not work with OR clauses --echo # create table t1 (a int, b int, primary key (a), key (b)); ---error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE update t1 set b=2 where a=1 or b=2; explain update t1 set b=2 where a=1 or b=2; ---error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE delete from t1 where a=1 or b=2; explain delete from t1 where a=1 or b=2; insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8); +explain update t1 set b=2 where a=1 or b=2; update t1 set b=2 where a=1 or b=2; +set @@optimizer_switch="index_merge=off"; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +update t1 set b=2 where a=1 or b=2; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE delete from t1 where a=1 or b=2; drop table t1; diff --git a/mysql-test/main/ssl.result b/mysql-test/main/ssl.result index 794830e5529..2694d177056 100644 --- a/mysql-test/main/ssl.result +++ b/mysql-test/main/ssl.result @@ -9,6 +9,7 @@ SHOW STATUS LIKE 'Ssl_server_not_after'; Variable_name Value Ssl_server_not_after Feb 27 03:03:03 2040 GMT drop table if exists t1,t2,t3,t4; +set @@default_storage_engine="aria"; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -609,6 +610,9 @@ explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +# +# Some test with ORDER BY and limit +# explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort @@ -1298,7 +1302,7 @@ companynr tinyint(2) unsigned zerofill NOT NULL default '00', companyname char(30) NOT NULL default '', PRIMARY KEY (companynr), UNIQUE KEY companyname(companyname) -) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +) ENGINE=aria MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; companynr companyname 00 Unknown @@ -1388,6 +1392,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t2 where fld1=999999; +# +# Test left join optimization +# explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where @@ -1402,15 +1409,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; id select_type table type possible_keys key key_len ref rows Extra @@ -1426,11 +1433,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/ssl_compress.result b/mysql-test/main/ssl_compress.result index 69de425cdc1..beb21ce8b16 100644 --- a/mysql-test/main/ssl_compress.result +++ b/mysql-test/main/ssl_compress.result @@ -6,6 +6,7 @@ SHOW STATUS LIKE 'Compression'; Variable_name Value Compression ON drop table if exists t1,t2,t3,t4; +set @@default_storage_engine="aria"; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL @@ -606,6 +607,9 @@ explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +# +# Some test with ORDER BY and limit +# explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using filesort @@ -1295,7 +1299,7 @@ companynr tinyint(2) unsigned zerofill NOT NULL default '00', companyname char(30) NOT NULL default '', PRIMARY KEY (companynr), UNIQUE KEY companyname(companyname) -) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +) ENGINE=aria MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; companynr companyname 00 Unknown @@ -1385,6 +1389,9 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE delete from t2 where fld1=999999; +# +# Test left join optimization +# explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where @@ -1399,15 +1406,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; id select_type table type possible_keys key key_len ref rows Extra @@ -1423,11 +1430,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t4 range PRIMARY PRIMARY 1 NULL 12 Using index condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/ssl_timeout.test b/mysql-test/main/ssl_timeout.test index f5965f874ff..60b45178d81 100644 --- a/mysql-test/main/ssl_timeout.test +++ b/mysql-test/main/ssl_timeout.test @@ -1,4 +1,6 @@ --source include/have_ssl_communication.inc +# Do not run this test with valgrind as may timeout +--source include/not_valgrind.inc # Save the initial number of concurrent sessions --source include/count_sessions.inc diff --git a/mysql-test/main/stat_tables.result b/mysql-test/main/stat_tables.result index 379e9737e1c..d9ee8cf14c4 100644 --- a/mysql-test/main/stat_tables.result +++ b/mysql-test/main/stat_tables.result @@ -214,10 +214,10 @@ order by o_year; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE region ALL PRIMARY NULL NULL NULL 5 Using where; Using temporary; Using filesort 1 SIMPLE part ALL PRIMARY NULL NULL NULL 200 Using where; Using join buffer (flat, BNL join) -1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_partkey 5 dbt3_s001.part.p_partkey 30 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey_partkey 5 dbt3_s001.part.p_partkey 30 Using index condition 1 SIMPLE supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.lineitem.l_suppkey 1 Using where 1 SIMPLE n2 eq_ref PRIMARY PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 -1 SIMPLE orders eq_ref PRIMARY,i_o_orderdate,i_o_custkey PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where +1 SIMPLE orders eq_ref|filter PRIMARY,i_o_orderdate,i_o_custkey PRIMARY|i_o_orderdate 4|4 dbt3_s001.lineitem.l_orderkey 1 (27%) Using where; Using rowid filter 1 SIMPLE customer eq_ref PRIMARY,i_c_nationkey PRIMARY 4 dbt3_s001.orders.o_custkey 1 Using where 1 SIMPLE n1 eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.customer.c_nationkey 1 Using where select o_year, @@ -251,12 +251,32 @@ and p_name like '%green%') as profit group by nation, o_year order by nation, o_year desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 Using where; Using temporary; Using filesort +1 SIMPLE part ALL PRIMARY NULL NULL NULL 200 Using where; Using temporary; Using filesort +1 SIMPLE partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 +1 SIMPLE supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) 1 SIMPLE nation eq_ref PRIMARY PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 -1 SIMPLE partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_suppkey 4 dbt3_s001.supplier.s_suppkey 70 -1 SIMPLE part eq_ref PRIMARY PRIMARY 4 dbt3_s001.partsupp.ps_partkey 1 Using where -1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.supplier.s_suppkey 8 +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey_partkey 10 dbt3_s001.part.p_partkey,dbt3_s001.partsupp.ps_suppkey 8 1 SIMPLE orders eq_ref PRIMARY PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 +EXPLAIN EXTENDED select nation, o_year, sum(amount) as sum_profit +from (select n_name as nation, +extract(year from o_orderdate) as o_year, +l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount +from part, supplier, lineitem, partsupp, orders, nation +where s_suppkey = l_suppkey and ps_suppkey = l_suppkey +and ps_partkey = l_partkey and p_partkey = l_partkey +and o_orderkey = l_orderkey and s_nationkey = n_nationkey +and p_name like '%green%') as profit +group by nation, o_year +order by nation, o_year desc; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE part ALL PRIMARY NULL NULL NULL 200 100.00 Using where; Using temporary; Using filesort +1 SIMPLE partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 +1 SIMPLE supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 10.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE nation eq_ref PRIMARY PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey_partkey 10 dbt3_s001.part.p_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 +1 SIMPLE orders eq_ref PRIMARY PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 100.00 +Warnings: +Note 1003 select `dbt3_s001`.`nation`.`n_name` AS `nation`,extract(year from `dbt3_s001`.`orders`.`o_orderDATE`) AS `o_year`,sum(`dbt3_s001`.`lineitem`.`l_extendedprice` * (1 - `dbt3_s001`.`lineitem`.`l_discount`) - `dbt3_s001`.`partsupp`.`ps_supplycost` * `dbt3_s001`.`lineitem`.`l_quantity`) AS `sum_profit` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`lineitem` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`orders` join `dbt3_s001`.`nation` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`orders`.`o_orderkey` = `dbt3_s001`.`lineitem`.`l_orderkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`part`.`p_name` like '%green%' group by `dbt3_s001`.`nation`.`n_name`,extract(year from `dbt3_s001`.`orders`.`o_orderDATE`) desc order by `dbt3_s001`.`nation`.`n_name`,extract(year from `dbt3_s001`.`orders`.`o_orderDATE`) desc select nation, o_year, sum(amount) as sum_profit from (select n_name as nation, extract(year from o_orderdate) as o_year, @@ -337,7 +357,7 @@ and o_orderkey=l_orderkey and p_partkey=l_partkey; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE part range PRIMARY,i_p_retailprice i_p_retailprice 9 NULL 1 Using index condition 1 SIMPLE orders ref PRIMARY,i_o_orderdate i_o_orderdate 4 const 1 -1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where select o_orderkey, p_partkey from part, lineitem, orders where p_retailprice > 1100 and o_orderdate='1997-01-01' @@ -412,7 +432,7 @@ EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 WHERE name IN ( 'AUS','YEM' ) AND id = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where ANALYZE TABLE t2; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected @@ -591,8 +611,8 @@ set @@use_stat_tables= PREFERABLY; explain SELECT * FROM INFORMATION_SCHEMA.PROFILING, mysql.user; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE PROFILING ALL NULL NULL NULL NULL NULL -1 SIMPLE global_priv ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) +1 SIMPLE global_priv ALL NULL NULL NULL NULL 5 +1 SIMPLE PROFILING ALL NULL NULL NULL NULL NULL Using join buffer (flat, BNL join) set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set use_stat_tables=@save_use_stat_tables; # diff --git a/mysql-test/main/stat_tables.test b/mysql-test/main/stat_tables.test index 7488ccb6877..8b9f8361d55 100644 --- a/mysql-test/main/stat_tables.test +++ b/mysql-test/main/stat_tables.test @@ -4,6 +4,7 @@ --source include/have_stat_tables.inc --source include/have_partition.inc +--source include/have_sequence.inc select @@global.use_stat_tables; select @@session.use_stat_tables; @@ -140,6 +141,7 @@ group by nation, o_year order by nation, o_year desc; eval EXPLAIN $Q9; +eval EXPLAIN EXTENDED $Q9; eval $Q9; diff --git a/mysql-test/main/stat_tables_innodb.result b/mysql-test/main/stat_tables_innodb.result index 5b62f228b1f..c90e99a9bbf 100644 --- a/mysql-test/main/stat_tables_innodb.result +++ b/mysql-test/main/stat_tables_innodb.result @@ -77,12 +77,12 @@ and r_name = 'AMERICA' and o_orderdate >= date '1995-01-01' group by n_name order by revenue desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE region ALL PRIMARY NULL NULL NULL 5 Using where; Using temporary; Using filesort -1 SIMPLE nation ref PRIMARY,i_n_regionkey i_n_regionkey 5 dbt3_s001.region.r_regionkey 5 -1 SIMPLE supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 Using index -1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index +1 SIMPLE supplier index PRIMARY,i_s_nationkey i_s_nationkey 5 NULL 10 Using where; Using index; Using temporary; Using filesort +1 SIMPLE nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 Using where +1 SIMPLE region eq_ref PRIMARY PRIMARY 4 dbt3_s001.nation.n_regionkey 1 Using where +1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.supplier.s_nationkey 6 Using index 1 SIMPLE orders ref|filter PRIMARY,i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (14%) Using where; Using rowid filter -1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey 9 dbt3_s001.supplier.s_suppkey,dbt3_s001.orders.o_orderkey 1 +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where select n_name, sum(l_extendedprice * (1 - l_discount)) as revenue from customer, orders, lineitem, supplier, nation, region where c_custkey = o_custkey and l_orderkey = o_orderkey @@ -208,12 +208,12 @@ and r_name = 'AMERICA' and o_orderdate >= date '1995-01-01' group by n_name order by revenue desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE region ALL PRIMARY NULL NULL NULL 5 Using where; Using temporary; Using filesort -1 SIMPLE nation ref PRIMARY,i_n_regionkey i_n_regionkey 5 dbt3_s001.region.r_regionkey 5 -1 SIMPLE supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 Using index -1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index +1 SIMPLE supplier index PRIMARY,i_s_nationkey i_s_nationkey 5 NULL 10 Using where; Using index; Using temporary; Using filesort +1 SIMPLE nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 Using where +1 SIMPLE region eq_ref PRIMARY PRIMARY 4 dbt3_s001.nation.n_regionkey 1 Using where +1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.supplier.s_nationkey 6 Using index 1 SIMPLE orders ref|filter PRIMARY,i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (14%) Using where; Using rowid filter -1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey 9 dbt3_s001.supplier.s_suppkey,dbt3_s001.orders.o_orderkey 1 +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where select n_name, sum(l_extendedprice * (1 - l_discount)) as revenue from customer, orders, lineitem, supplier, nation, region where c_custkey = o_custkey and l_orderkey = o_orderkey @@ -246,12 +246,12 @@ order by o_year; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE region ALL PRIMARY NULL NULL NULL 5 Using where; Using temporary; Using filesort 1 SIMPLE part ALL PRIMARY NULL NULL NULL 200 Using where; Using join buffer (flat, BNL join) -1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_partkey 5 dbt3_s001.part.p_partkey 30 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey_partkey 5 dbt3_s001.part.p_partkey 30 Using index condition 1 SIMPLE supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.lineitem.l_suppkey 1 Using where 1 SIMPLE n2 eq_ref PRIMARY PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 1 SIMPLE orders eq_ref PRIMARY,i_o_orderdate,i_o_custkey PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 Using where 1 SIMPLE customer eq_ref PRIMARY,i_c_nationkey PRIMARY 4 dbt3_s001.orders.o_custkey 1 Using where -1 SIMPLE n1 eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.customer.c_nationkey 1 Using where +1 SIMPLE n1 eq_ref PRIMARY,i_n_regionkey i_n_regionkey 9 dbt3_s001.region.r_regionkey,dbt3_s001.customer.c_nationkey 1 Using index select o_year, sum(case when nation = 'UNITED STATES' then volume else 0 end) / sum(volume) as mkt_share @@ -289,6 +289,26 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE part eq_ref PRIMARY PRIMARY 4 dbt3_s001.partsupp.ps_partkey 1 Using where 1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.supplier.s_suppkey 8 1 SIMPLE orders eq_ref PRIMARY PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 +EXPLAIN EXTENDED select nation, o_year, sum(amount) as sum_profit +from (select n_name as nation, +extract(year from o_orderdate) as o_year, +l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount +from part, supplier, lineitem, partsupp, orders, nation +where s_suppkey = l_suppkey and ps_suppkey = l_suppkey +and ps_partkey = l_partkey and p_partkey = l_partkey +and o_orderkey = l_orderkey and s_nationkey = n_nationkey +and p_name like '%green%') as profit +group by nation, o_year +order by nation, o_year desc; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE supplier index PRIMARY,i_s_nationkey i_s_nationkey 5 NULL 10 100.00 Using where; Using index; Using temporary; Using filesort +1 SIMPLE nation eq_ref PRIMARY PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 +1 SIMPLE partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_suppkey 4 dbt3_s001.supplier.s_suppkey 70 100.00 +1 SIMPLE part eq_ref PRIMARY PRIMARY 4 dbt3_s001.partsupp.ps_partkey 1 100.00 Using where +1 SIMPLE lineitem ref PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.supplier.s_suppkey 8 100.00 +1 SIMPLE orders eq_ref PRIMARY PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 100.00 +Warnings: +Note 1003 select `dbt3_s001`.`nation`.`n_name` AS `nation`,extract(year from `dbt3_s001`.`orders`.`o_orderDATE`) AS `o_year`,sum(`dbt3_s001`.`lineitem`.`l_extendedprice` * (1 - `dbt3_s001`.`lineitem`.`l_discount`) - `dbt3_s001`.`partsupp`.`ps_supplycost` * `dbt3_s001`.`lineitem`.`l_quantity`) AS `sum_profit` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`lineitem` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`orders` join `dbt3_s001`.`nation` where `dbt3_s001`.`partsupp`.`ps_suppkey` = `dbt3_s001`.`supplier`.`s_suppkey` and `dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`supplier`.`s_suppkey` and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey` and `dbt3_s001`.`orders`.`o_orderkey` = `dbt3_s001`.`lineitem`.`l_orderkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`part`.`p_name` like '%green%' group by `dbt3_s001`.`nation`.`n_name`,extract(year from `dbt3_s001`.`orders`.`o_orderDATE`) desc order by `dbt3_s001`.`nation`.`n_name`,extract(year from `dbt3_s001`.`orders`.`o_orderDATE`) desc select nation, o_year, sum(amount) as sum_profit from (select n_name as nation, extract(year from o_orderdate) as o_year, @@ -444,7 +464,7 @@ EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 WHERE name IN ( 'AUS','YEM' ) AND id = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index -1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where ANALYZE TABLE t2; Table Op Msg_type Msg_text test.t2 analyze status Engine-independent statistics collected @@ -623,8 +643,8 @@ set @@use_stat_tables= PREFERABLY; explain SELECT * FROM INFORMATION_SCHEMA.PROFILING, mysql.user; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE PROFILING ALL NULL NULL NULL NULL NULL -1 SIMPLE global_priv ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) +1 SIMPLE global_priv ALL NULL NULL NULL NULL 5 +1 SIMPLE PROFILING ALL NULL NULL NULL NULL NULL Using join buffer (flat, BNL join) set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set use_stat_tables=@save_use_stat_tables; # diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result index 748287152b1..a4cf71f9806 100644 --- a/mysql-test/main/statistics_json.result +++ b/mysql-test/main/statistics_json.result @@ -8338,12 +8338,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 18, + "cost": "COST_REPLACED", "filtered": 5.555555344, "attached_condition": "t1.a > 'y'" } diff --git a/mysql-test/main/statistics_json.test b/mysql-test/main/statistics_json.test index 5263a98fff7..b9a5c3dbea2 100644 --- a/mysql-test/main/statistics_json.test +++ b/mysql-test/main/statistics_json.test @@ -477,6 +477,7 @@ INSERT INTO t1 VALUES ('o'),('s'),('j'),('s'),('y'),('s'),('l'), set histogram_type=json_hb; analyze table t1 persistent for all; --echo # filtered must not be negative: +--source include/explain-no-costs.inc explain format=json select * from t1 where a > 'y'; drop table t1; diff --git a/mysql-test/main/status.result b/mysql-test/main/status.result index d17bd9c6a61..0669bdf3b34 100644 --- a/mysql-test/main/status.result +++ b/mysql-test/main/status.result @@ -71,10 +71,10 @@ a 6 show status like 'last_query_cost'; Variable_name Value -Last_query_cost 12.084449 +Last_query_cost 0.017856 show status like 'last_query_cost'; Variable_name Value -Last_query_cost 12.084449 +Last_query_cost 0.017856 select 1; 1 1 @@ -134,20 +134,20 @@ a 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 2.402418 +Last_query_cost 0.010348 EXPLAIN SELECT a FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 2.402418 +Last_query_cost 0.010348 SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; a 1 2 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 0.000000 +Last_query_cost 0.010348 EXPLAIN SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 @@ -155,25 +155,25 @@ id select_type table type possible_keys key key_len ref rows Extra NULL UNION RESULT ALL NULL NULL NULL NULL NULL Using filesort SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 0.000000 +Last_query_cost 0.010348 SELECT a IN (SELECT a FROM t1) FROM t1 LIMIT 1; a IN (SELECT a FROM t1) 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 0.000000 +Last_query_cost 0.010348 SELECT (SELECT a FROM t1 LIMIT 1) x FROM t1 LIMIT 1; x 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 0.000000 +Last_query_cost 0.010348 SELECT * FROM t1 a, t1 b LIMIT 1; a a 1 1 SHOW SESSION STATUS LIKE 'Last_query_cost'; Variable_name Value -Last_query_cost 5.205836 +Last_query_cost 0.021190 DROP TABLE t1; connect con1,localhost,root,,; show status like 'com_show_status'; diff --git a/mysql-test/main/subselect.result b/mysql-test/main/subselect.result index 4209e2bc529..77d80405b3b 100644 --- a/mysql-test/main/subselect.result +++ b/mysql-test/main/subselect.result @@ -345,7 +345,7 @@ patient_uq clinic_uq explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index -1 PRIMARY t6 ALL i1 NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t6 ref i1 i1 5 test.t7.uq 1 100.00 Warnings: Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t7` join `test`.`t6` where `test`.`t6`.`clinic_uq` = `test`.`t7`.`uq` @@ -895,6 +895,9 @@ select (select a+1) from t1; NULL 4.5 drop table t1; +# +# Null with keys +# CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a)); CREATE TABLE t2 (a int(11) default '0', INDEX (a)); INSERT INTO t1 VALUES (1),(2),(3),(4); @@ -1426,6 +1429,9 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); a 1 +# +# IN subselect optimization test +# create table t1 (a int not null, b int, primary key (a)); create table t2 (a int not null, primary key (a)); create table t3 (a int not null, b int, primary key (a)); @@ -1449,21 +1455,21 @@ a 4 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using where +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 3 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 -1 PRIMARY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where `test`.`t3`.`a` = `test`.`t1`.`b` and `test`.`t1`.`a` = `test`.`t2`.`a` +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where `test`.`t3`.`a` = `test`.`t1`.`b` and `test`.`t2`.`a` = `test`.`t1`.`a` drop table t1, t2, t3; create table t1 (a int, b int, index a (a,b)); create table t2 (a int, index a (a)); @@ -1472,42 +1478,48 @@ insert into t1 values (1,10), (2,20), (3,30), (4,40); create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 -select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D; +select rand()*100000+200,rand(1)*100000 from t0 A, t0 B, t0 C, t0 D; insert into t2 values (2), (3), (4), (5); insert into t3 values (10,3), (20,4), (30,5); +explain extended select * from t2 where t2.a in (select a from t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using index; FirstMatch(t2) +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` select * from t2 where t2.a in (select a from t1); a 2 3 4 -explain extended select * from t2 where t2.a in (select a from t1); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2) +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using where; Using index; FirstMatch(t2) Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2) -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 -select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); -a -2 -3 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index 1 PRIMARY t3 range a a 5 NULL 3 100.00 Using where; Using index -1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2) +1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 0.29 Using index; FirstMatch(t2) Warnings: Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where `test`.`t1`.`b` = `test`.`t3`.`a` and `test`.`t1`.`a` = `test`.`t2`.`a` +select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +a +2 +3 insert into t1 values (3,31); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using where; Using index; FirstMatch(t2) +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 @@ -1517,12 +1529,6 @@ select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31 a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2) -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 drop table t0, t1, t2, t3; create table t1 (a int, b int); create table t2 (a int, b int); @@ -1584,6 +1590,9 @@ Note 1003 (select 'tttt' AS `s1` from dual) s1 tttt drop table t1; +# +# IN optimisation test results +# create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); @@ -2417,20 +2426,23 @@ a 1 3 DROP TABLE t1; +# +# SELECT(EXISTS * ...)optimisation +# create table t1 (a int, b int); -insert into t1 values (1,2),(3,4); -select * from t1 up where exists (select * from t1 where t1.a=up.a); -a b -1 2 -3 4 -explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a); +insert into t1 values (1,2),(3,4),(5,6),(7,8); +insert into t1 select seq,seq from seq_20_to_40; +select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); +sum(a+b) +1296 +explain extended select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY up ALL NULL NULL NULL NULL 25 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 25 100.00 Warnings: Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` semi join (`test`.`t1`) where 1 +Note 1003 select sum(`test`.`up`.`a` + `test`.`up`.`b`) AS `sum(a+b)` from `test`.`t1` `up` semi join (`test`.`t1`) where 1 drop table t1; CREATE TABLE t1 (t1_a int); INSERT INTO t1 VALUES (1); @@ -3098,9 +3110,13 @@ retailerID statusID changed 0048 1 2006-01-06 12:37:50 0059 1 2006-01-06 12:37:50 drop table t1; +# +# Bug#21180 Subselect with index for both WHERE and ORDER BY +# produces empty result +# create table t1(a int, primary key (a)); insert into t1 values (10); -create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +create table t2 (a int primary key, b varchar(32), c int, unique key cb(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); analyze table t1; @@ -3113,7 +3129,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using where +2 SUBQUERY t2 range cb cb 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3125,7 +3141,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using index condition +2 SUBQUERY t2 range cb cb 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -4225,8 +4241,8 @@ INSERT INTO t2 VALUES (7), (5), (1), (3); SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); id st -3 FL 1 GA +3 FL 7 FL SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) @@ -4327,6 +4343,9 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; 0 0 DROP TABLE t1, t2; +# +# Bug#28076 inconsistent binary/varbinary comparison +# CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)); INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43); SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1); @@ -4388,8 +4407,8 @@ CREATE INDEX I1 ON t1 (a); CREATE INDEX I2 ON t1 (b); EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1) +1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using index condition SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); a b CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10)); @@ -4398,15 +4417,15 @@ CREATE INDEX I1 ON t2 (a); CREATE INDEX I2 ON t2 (b); EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t2 ref I1 I1 4 test.t2.b 2 Using where; Using index; FirstMatch(t2) +1 PRIMARY t2 index I1 I1 4 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t2 ref I2 I2 13 test.t2.a 1 Using index condition SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); a b EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1) +1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using index condition SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); a b DROP TABLE t1,t2; @@ -4436,10 +4455,13 @@ out_a MIN(b) 1 2 2 4 DROP TABLE t1; +# +# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +# CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); -INSERT INTO t1 VALUES (1),(2); -INSERT INTO t2 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1),(2),(1000); SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); 2 2 @@ -4447,19 +4469,18 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where 1 +Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`a` EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 3 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 @@ -5698,7 +5719,8 @@ DROP TABLE IF EXISTS ot1, ot4, it2, it3; CREATE TABLE t1 (a int) ; INSERT INTO t1 VALUES (NULL), (1), (NULL), (2); CREATE TABLE t2 (a int, INDEX idx(a)) ; -INSERT INTO t2 VALUES (NULL), (1), (NULL); +INSERT INTO t2 VALUES (NULL), (1), (NULL),(1000); +insert into t2 select seq from seq_3_to_500; SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a); a @@ -5709,7 +5731,7 @@ WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 502 SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); a @@ -5718,9 +5740,8 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 index idx idx 5 NULL 3 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t2 ref idx idx 5 test.t1.a 11 Using index; FirstMatch(t1) DROP TABLE t1,t2; # # BUG#752992: Wrong results for a subquery with 'semijoin=on' @@ -5737,9 +5758,9 @@ SET @save_join_cache_level=@@join_cache_level; SET join_cache_level=0; EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3 -1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index -1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(it) +1 PRIMARY it index PRIMARY PRIMARY 4 NULL 3 Using index +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.it.pk 1 +1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(t1) SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); pk i 11 0 @@ -6080,8 +6101,7 @@ WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index +1 PRIMARY it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index; FirstMatch(ot) SELECT col_int_nokey FROM ot WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); @@ -6093,8 +6113,7 @@ WHERE (col_varchar_nokey, 'x') IN (SELECT col_varchar_key, col_varchar_key2 FROM it2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index +1 PRIMARY it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index; FirstMatch(ot) SELECT col_int_nokey FROM ot WHERE (col_varchar_nokey, 'x') IN (SELECT col_varchar_key, col_varchar_key2 FROM it2); @@ -6638,7 +6657,7 @@ SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquer EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 1 Using index SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); a 2009-01-01 @@ -6841,7 +6860,7 @@ FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 WHERE alias1.a = alias2.a OR ('Moscow') IN ( SELECT a FROM t1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY alias1 index a a 19 NULL 11 Using where; Using index -1 PRIMARY alias2 ref a a 19 test.alias1.a 2 Using index +1 PRIMARY alias2 ref a a 19 test.alias1.a 1 Using index 1 PRIMARY alias3 index NULL a 19 NULL 11 Using index; Using join buffer (flat, BNL join) 2 SUBQUERY t1 index_subquery a a 19 const 1 Using index; Using where SELECT MAX( alias2.a ) @@ -6992,7 +7011,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index +1 PRIMARY t3 ref d d 5 test.t2.b 1 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; @@ -7024,7 +7043,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields @@ -7058,7 +7077,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-5991: crash in Item_field::used_tables diff --git a/mysql-test/main/subselect.test b/mysql-test/main/subselect.test index be22169a1d6..48ad7402755 100644 --- a/mysql-test/main/subselect.test +++ b/mysql-test/main/subselect.test @@ -7,6 +7,7 @@ # as possible. # # Initialise +--source include/have_sequence.inc --disable_warnings drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12; drop view if exists v2; @@ -537,9 +538,9 @@ select (select a+1) from t1; drop table t1; --enable_view_protocol -# -# Null with keys -# +--echo # +--echo # Null with keys +--echo # CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a)); CREATE TABLE t2 (a int(11) default '0', INDEX (a)); @@ -906,9 +907,9 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); -# -# IN subselect optimization test -# +--echo # +--echo # IN subselect optimization test +--echo # create table t1 (a int not null, b int, primary key (a)); create table t2 (a int not null, primary key (a)); create table t3 (a int not null, b int, primary key (a)); @@ -930,20 +931,20 @@ insert into t1 values (1,10), (2,20), (3,30), (4,40); create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 -select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D; +select rand()*100000+200,rand(1)*100000 from t0 A, t0 B, t0 C, t0 D; insert into t2 values (2), (3), (4), (5); insert into t3 values (10,3), (20,4), (30,5); -select * from t2 where t2.a in (select a from t1); explain extended select * from t2 where t2.a in (select a from t1); -select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +select * from t2 where t2.a in (select a from t1); explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +select * from t2 where t2.a in (select a from t1 where t1.b <> 30); explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); insert into t1 values (3,31); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); select * from t2 where t2.a in (select a from t1 where t1.b <> 30); select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31); -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); drop table t0, t1, t2, t3; # @@ -1017,13 +1018,14 @@ explain extended (select * from t1); (select * from t1); drop table t1; -# -# IN optimisation test results -# +--echo # +--echo # IN optimisation test results +--echo # create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); insert into t2 values ('a1'),('a2'); + select s1, s1 NOT IN (SELECT s1 FROM t2) from t1; select s1, s1 = ANY (SELECT s1 FROM t2) from t1; select s1, s1 <> ALL (SELECT s1 FROM t2) from t1; @@ -1450,15 +1452,16 @@ SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2'); DROP TABLE t1; -# -# SELECT(EXISTS * ...)optimisation -# +--echo # +--echo # SELECT(EXISTS * ...)optimisation +--echo # #--view-protocol is disabled because view gives another query plan --disable_view_protocol create table t1 (a int, b int); -insert into t1 values (1,2),(3,4); -select * from t1 up where exists (select * from t1 where t1.a=up.a); -explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a); +insert into t1 values (1,2),(3,4),(5,6),(7,8); +insert into t1 select seq,seq from seq_20_to_40; +select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); +explain extended select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); drop table t1; --enable_view_protocol @@ -2059,14 +2062,14 @@ select * from t1 r1 drop table t1; -# -# Bug#21180 Subselect with index for both WHERE and ORDER BY -# produces empty result -# +--echo # +--echo # Bug#21180 Subselect with index for both WHERE and ORDER BY +--echo # produces empty result +--echo # create table t1(a int, primary key (a)); insert into t1 values (10); -create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +create table t2 (a int primary key, b varchar(32), c int, unique key cb(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); analyze table t1; @@ -3098,6 +3101,7 @@ INSERT INTO t1 VALUES CREATE TABLE t2 (id int NOT NULL, INDEX idx(id)); INSERT INTO t2 VALUES (7), (5), (1), (3); +--sorted_result SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); SELECT id, st FROM t1 @@ -3272,9 +3276,9 @@ DROP TABLE t1, t2; #--enable_query_log #drop table t1; -# -# Bug#28076 inconsistent binary/varbinary comparison -# +--echo # +--echo # Bug#28076 inconsistent binary/varbinary comparison +--echo # CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)); INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43); @@ -3376,15 +3380,15 @@ GROUP BY a; DROP TABLE t1; -# -# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 -# +--echo # +--echo # Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +--echo # CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); -INSERT INTO t1 VALUES (1),(2); -INSERT INTO t2 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1),(2),(1000); SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); EXPLAIN EXTENDED @@ -4853,7 +4857,8 @@ CREATE TABLE t1 (a int) ; INSERT INTO t1 VALUES (NULL), (1), (NULL), (2); CREATE TABLE t2 (a int, INDEX idx(a)) ; -INSERT INTO t2 VALUES (NULL), (1), (NULL); +INSERT INTO t2 VALUES (NULL), (1), (NULL),(1000); +insert into t2 select seq from seq_3_to_500; SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a); diff --git a/mysql-test/main/subselect2.result b/mysql-test/main/subselect2.result index ebeda9a64af..e62f0617574 100644 --- a/mysql-test/main/subselect2.result +++ b/mysql-test/main/subselect2.result @@ -125,8 +125,8 @@ DOCID DOCNAME DOCTYPEID FOLDERID AUTHOR CREATED TITLE SUBTITLE DOCABSTRACT PUBLI c373e9f5ad07993f3859444553544200 Last Discussion c373e9f5ad079174ff17444553544200 c373e9f5ad0796c0eca4444553544200 Goldilocks 2003-06-09 11:21:06 Title: Last Discussion NULL Setting new abstract and keeping doc checked out 2003-06-09 10:51:26 2003-06-09 10:51:26 NULL NULL NULL 03eea05112b845949f3fd03278b5fe43 2003-06-09 11:21:06 admin 0 NULL Discussion NULL NULL EXPLAIN SELECT t2.*, t4.DOCTYPENAME, t1.CONTENTSIZE,t1.MIMETYPE FROM t2 INNER JOIN t4 ON t2.DOCTYPEID = t4.DOCTYPEID LEFT OUTER JOIN t1 ON t2.DOCID = t1.DOCID WHERE t2.FOLDERID IN(SELECT t3_a.FOLDERID FROM t3 as t3_a WHERE t3_a.PARENTID IN(SELECT t3_b.FOLDERID FROM t3 as t3_b WHERE t3_b.PARENTID IN(SELECT t3_c.FOLDERID FROM t3 as t3_c WHERE t3_c.PARENTID IN(SELECT t3_d.FOLDERID FROM t3 as t3_d WHERE t3_d.PARENTID IN(SELECT t3_e.FOLDERID FROM t3 as t3_e WHERE t3_e.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t3_e.FOLDERNAME = 'Level1') AND t3_d.FOLDERNAME = 'Level2') AND t3_c.FOLDERNAME = 'Level3') AND t3_b.FOLDERNAME = 'CopiedFolder') AND t3_a.FOLDERNAME = 'Movie Reviews') AND t2.DOCNAME = 'Last Discussion'; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL DDOCTYPEID_IDX,DFOLDERID_IDX NULL NULL NULL 9 Using where -1 PRIMARY t4 eq_ref PRIMARY PRIMARY 34 test.t2.DOCTYPEID 1 +1 PRIMARY t4 ALL PRIMARY NULL NULL NULL 10 +1 PRIMARY t2 ALL DDOCTYPEID_IDX,DFOLDERID_IDX NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 34 test.t2.DOCID 1 1 PRIMARY t3_a eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t2.FOLDERID 1 Using where 1 PRIMARY t3_b eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3_a.PARENTID 1 Using where @@ -162,8 +162,8 @@ EXPLAIN SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM t1) OR a = b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index a a 5 NULL 2 Using where; Using index -1 PRIMARY t3 ref b b 5 test.t2.a 2 Using index -2 SUBQUERY t1 const PRIMARY,a PRIMARY 4 const 1 Using where +1 PRIMARY t3 ref b b 5 test.t2.a 1 Using index +2 SUBQUERY t1 const PRIMARY,a a 9 const,const 1 Using where; Using index SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM t1) OR a = b; pk a b 0 4 4 @@ -171,8 +171,8 @@ EXPLAIN SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM v1) OR a = b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index a a 5 NULL 2 Using where; Using index -1 PRIMARY t3 ref b b 5 test.t2.a 2 Using index -2 SUBQUERY t1 const PRIMARY,a PRIMARY 4 const 1 Using where +1 PRIMARY t3 ref b b 5 test.t2.a 1 Using index +2 SUBQUERY t1 const PRIMARY,a a 9 const,const 1 Using where; Using index SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM v1) OR a = b; pk a b 0 4 4 @@ -277,7 +277,7 @@ KEY `date` (`date`) INSERT INTO `t1` VALUES (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00'); INSERT INTO `t1` VALUES (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00'); INSERT INTO `t1` VALUES (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00'); -explain +set statement optimizer_scan_setup_cost=0 for explain SELECT * FROM ( SELECT node_uid, date, mirror_date, @result := 0 AS result FROM t1 @@ -286,9 +286,9 @@ WHERE date < '2012-12-12 12:12:12' ORDER BY mirror_date ASC ) AS calculated_result; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 3 -2 DERIVED t1 range date date 6 NULL 3 Using index condition; Using where; Rowid-ordered scan; Using filesort -SELECT * FROM ( +1 PRIMARY ALL NULL NULL NULL NULL 3 +3 DERIVED t1 ALL date NULL NULL NULL 3 Using where; Using filesort +set statement optimizer_scan_setup_cost=0 FOR SELECT * FROM ( SELECT node_uid, date, mirror_date, @result := 0 AS result FROM t1 WHERE date < '2012-12-12 12:12:12' @@ -339,7 +339,7 @@ where t1.a = t2.a and ( t1.a = ( select min(a) from t1 ) or 0 ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) -1 PRIMARY t3 ref idx idx 6 func 2 100.00 Using where; Using index +1 PRIMARY t3 ref idx idx 6 func 1 100.00 Using where; Using index 2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on(`test`.`t3`.`a` = `test`.`t1`.`a`) where `test`.`t1`.`a` = (/* select#2 */ select min(`test`.`t1`.`a`) from `test`.`t1`) and `test`.`t2`.`a` = (/* select#2 */ select min(`test`.`t1`.`a`) from `test`.`t1`) diff --git a/mysql-test/main/subselect2.test b/mysql-test/main/subselect2.test index b341e516941..0780a5b9319 100644 --- a/mysql-test/main/subselect2.test +++ b/mysql-test/main/subselect2.test @@ -303,7 +303,7 @@ INSERT INTO `t1` VALUES (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00'); INSERT INTO `t1` VALUES (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00'); INSERT INTO `t1` VALUES (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00'); -explain +set statement optimizer_scan_setup_cost=0 for explain SELECT * FROM ( SELECT node_uid, date, mirror_date, @result := 0 AS result FROM t1 @@ -312,7 +312,7 @@ SELECT * FROM ( ORDER BY mirror_date ASC ) AS calculated_result; -SELECT * FROM ( +set statement optimizer_scan_setup_cost=0 FOR SELECT * FROM ( SELECT node_uid, date, mirror_date, @result := 0 AS result FROM t1 WHERE date < '2012-12-12 12:12:12' diff --git a/mysql-test/main/subselect3.inc b/mysql-test/main/subselect3.inc index af7b45542bd..b78d5ed444f 100644 --- a/mysql-test/main/subselect3.inc +++ b/mysql-test/main/subselect3.inc @@ -1110,6 +1110,7 @@ insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 as select a as a, a as b, a as c from t0 where a < 3; create table t2 as select a as a, a as b from t0 where a < 3; insert into t2 select * from t2; +select count(*) from t2; explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33); @@ -1155,7 +1156,7 @@ drop table t0, t1; create table t1 ( idIndividual int primary key ); -insert into t1 values (1),(2); +insert into t1 values (1),(2),(1000); create table t2 ( idContact int primary key, @@ -1170,12 +1171,18 @@ create table t3 ( postalStripped varchar(100) ); -insert into t3 values (1,1, 'foo'), (2,2,'bar'); +insert into t3 values (1,1, 'foo'), (2,2,'T2H3B2'); --echo The following must be converted to a semi-join: set @save_optimizer_switch=@@optimizer_switch; set @@optimizer_switch='materialization=off'; explain extended SELECT a.idIndividual FROM t1 a +WHERE a.idIndividual IN + ( SELECT c.idObj FROM t3 cona + INNER JOIN t2 c ON c.idContact=cona.idContact + WHERE cona.postalStripped='T2H3B2' + ); +SELECT a.idIndividual FROM t1 a WHERE a.idIndividual IN ( SELECT c.idObj FROM t3 cona INNER JOIN t2 c ON c.idContact=cona.idContact diff --git a/mysql-test/main/subselect3.result b/mysql-test/main/subselect3.result index 28187e0ffdd..e8e91ec2cc2 100644 --- a/mysql-test/main/subselect3.result +++ b/mysql-test/main/subselect3.result @@ -96,10 +96,10 @@ explain extended select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 100.00 -2 DEPENDENT SUBQUERY t1 ALL a NULL NULL NULL 8 100.00 Using where +2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 3 100.00 Using where; Full scan on NULL key Warnings: Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<`test`.`t2`.`a`,`test`.`t2`.`oref`>((`test`.`t2`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`oref` = `test`.`t2`.`oref` and trigcond((`test`.`t2`.`a`) = `test`.`t1`.`a` or `test`.`t1`.`a` is null) having trigcond(`test`.`t1`.`a` is null)))) AS `Z` from `test`.`t2` +Note 1003 /* select#1 */ select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<`test`.`t2`.`a`,`test`.`t2`.`oref`>((`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a checking NULL where `test`.`t1`.`oref` = `test`.`t2`.`oref` having trigcond(`test`.`t1`.`a` is null))))) AS `Z` from `test`.`t2` flush status; select oref, a from t2 where a in (select a from t1 where oref=t2.oref); oref a @@ -193,7 +193,7 @@ t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z from t3; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 -2 DEPENDENT SUBQUERY t1 ref a a 4 func 2 100.00 Using where; Full scan on NULL key +2 DEPENDENT SUBQUERY t1 ref a a 4 func 1 100.00 Using where; Full scan on NULL key 2 DEPENDENT SUBQUERY t2 ref a a 4 test.t1.b 1 100.00 Using where Warnings: Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1 @@ -1157,9 +1157,9 @@ set @@optimizer_switch='firstmatch=off,materialization=off'; set @@max_heap_table_size= 16384; explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY A ALL NULL NULL NULL NULL 10 +1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary +1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) 1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) -1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary; Using join buffer (flat, BNL join) 1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) 1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (flat, BNL join) flush status; @@ -1180,9 +1180,8 @@ create table t3 ( a int , filler char(100), key(a)); insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B; explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 ref a a 5 test.t2.a 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary +1 PRIMARY t3 ref a a 5 test.t2.a 1 End temporary select * from t3 where a in (select a from t2); a filler 1 filler @@ -1336,6 +1335,9 @@ insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 as select a as a, a as b, a as c from t0 where a < 3; create table t2 as select a as a, a as b from t0 where a < 3; insert into t2 select * from t2; +select count(*) from t2; +count(*) +6 explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 @@ -1391,7 +1393,7 @@ drop table t0, t1; create table t1 ( idIndividual int primary key ); -insert into t1 values (1),(2); +insert into t1 values (1),(2),(1000); create table t2 ( idContact int primary key, contactType int, @@ -1403,7 +1405,7 @@ idAddress int primary key, idContact int, postalStripped varchar(100) ); -insert into t3 values (1,1, 'foo'), (2,2,'bar'); +insert into t3 values (1,1, 'foo'), (2,2,'T2H3B2'); The following must be converted to a semi-join: set @save_optimizer_switch=@@optimizer_switch; set @@optimizer_switch='materialization=off'; @@ -1416,9 +1418,17 @@ WHERE cona.postalStripped='T2H3B2' id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY cona ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary 1 PRIMARY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using where -1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.c.idObj 1 100.00 Using index; End temporary +1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.c.idObj 1 50.00 Using index; End temporary Warnings: Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where `test`.`cona`.`postalStripped` = 'T2H3B2' and `test`.`a`.`idIndividual` = `test`.`c`.`idObj` and `test`.`c`.`idContact` = `test`.`cona`.`idContact` +SELECT a.idIndividual FROM t1 a +WHERE a.idIndividual IN +( SELECT c.idObj FROM t3 cona +INNER JOIN t2 c ON c.idContact=cona.idContact +WHERE cona.postalStripped='T2H3B2' + ); +idIndividual +2 set @@optimizer_switch=@save_optimizer_switch; drop table t1,t2,t3; # diff --git a/mysql-test/main/subselect3_jcl6.result b/mysql-test/main/subselect3_jcl6.result index 9df821e07dc..4fc6f713088 100644 --- a/mysql-test/main/subselect3_jcl6.result +++ b/mysql-test/main/subselect3_jcl6.result @@ -99,10 +99,10 @@ explain extended select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 100.00 -2 DEPENDENT SUBQUERY t1 ALL a NULL NULL NULL 8 100.00 Using where +2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 3 100.00 Using where; Full scan on NULL key Warnings: Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<`test`.`t2`.`a`,`test`.`t2`.`oref`>((`test`.`t2`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`oref` = `test`.`t2`.`oref` and trigcond((`test`.`t2`.`a`) = `test`.`t1`.`a` or `test`.`t1`.`a` is null) having trigcond(`test`.`t1`.`a` is null)))) AS `Z` from `test`.`t2` +Note 1003 /* select#1 */ select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<`test`.`t2`.`a`,`test`.`t2`.`oref`>((`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a checking NULL where `test`.`t1`.`oref` = `test`.`t2`.`oref` having trigcond(`test`.`t1`.`a` is null))))) AS `Z` from `test`.`t2` flush status; select oref, a from t2 where a in (select a from t1 where oref=t2.oref); oref a @@ -196,7 +196,7 @@ t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z from t3; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 -2 DEPENDENT SUBQUERY t1 ref a a 4 func 2 100.00 Using where; Full scan on NULL key +2 DEPENDENT SUBQUERY t1 ref a a 4 func 1 100.00 Using where; Full scan on NULL key 2 DEPENDENT SUBQUERY t2 ref a a 4 test.t1.b 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1 @@ -1160,9 +1160,9 @@ set @@optimizer_switch='firstmatch=off,materialization=off'; set @@max_heap_table_size= 16384; explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY A ALL NULL NULL NULL NULL 10 -1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) -1 PRIMARY E ALL NULL NULL NULL NULL 5 Using where; Start temporary; Using join buffer (incremental, BNL join) +1 PRIMARY E ALL NULL NULL NULL NULL 5 Using where; Start temporary +1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) +1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join) 1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; Using join buffer (incremental, BNL join) 1 PRIMARY D hash_ALL NULL #hash#$hj 5 test.E.a 10 Using where; End temporary; Using join buffer (incremental, BNLH join) flush status; @@ -1183,9 +1183,8 @@ create table t3 ( a int , filler char(100), key(a)); insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B; explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 ref a a 5 test.t2.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary +1 PRIMARY t3 ref a a 5 test.t2.a 1 End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan select * from t3 where a in (select a from t2); a filler 1 filler @@ -1339,6 +1338,9 @@ insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 as select a as a, a as b, a as c from t0 where a < 3; create table t2 as select a as a, a as b from t0 where a < 3; insert into t2 select * from t2; +select count(*) from t2; +count(*) +6 explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where @@ -1394,7 +1396,7 @@ drop table t0, t1; create table t1 ( idIndividual int primary key ); -insert into t1 values (1),(2); +insert into t1 values (1),(2),(1000); create table t2 ( idContact int primary key, contactType int, @@ -1406,7 +1408,7 @@ idAddress int primary key, idContact int, postalStripped varchar(100) ); -insert into t3 values (1,1, 'foo'), (2,2,'bar'); +insert into t3 values (1,1, 'foo'), (2,2,'T2H3B2'); The following must be converted to a semi-join: set @save_optimizer_switch=@@optimizer_switch; set @@optimizer_switch='materialization=off'; @@ -1419,9 +1421,17 @@ WHERE cona.postalStripped='T2H3B2' id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY cona ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary 1 PRIMARY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.c.idObj 1 100.00 Using index; End temporary +1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.c.idObj 1 50.00 Using index; End temporary Warnings: Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where `test`.`cona`.`postalStripped` = 'T2H3B2' and `test`.`a`.`idIndividual` = `test`.`c`.`idObj` and `test`.`c`.`idContact` = `test`.`cona`.`idContact` +SELECT a.idIndividual FROM t1 a +WHERE a.idIndividual IN +( SELECT c.idObj FROM t3 cona +INNER JOIN t2 c ON c.idContact=cona.idContact +WHERE cona.postalStripped='T2H3B2' + ); +idIndividual +2 set @@optimizer_switch=@save_optimizer_switch; drop table t1,t2,t3; # diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index 5589272d066..382e4044081 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -265,7 +265,7 @@ EXPLAIN SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 DEPENDENT SUBQUERY t2c index_subquery it2c it2c 8 const,test.t1.pk 2 Using index; Using where; Full scan on NULL key +2 DEPENDENT SUBQUERY t2c index_subquery it2c it2c 8 const,test.t1.pk 1 Using index; Using where; Full scan on NULL key SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk); pk i SELECT * FROM t1 WHERE NULL IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk) IS UNKNOWN; @@ -335,7 +335,7 @@ EXPLAIN SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 DEPENDENT SUBQUERY t2c index_subquery it2c it2c 8 const,test.t1.pk 2 Using index; Using where; Full scan on NULL key +2 DEPENDENT SUBQUERY t2c index_subquery it2c it2c 8 const,test.t1.pk 1 Using index; Using where; Full scan on NULL key SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk); pk i 0 10 @@ -714,8 +714,7 @@ WHERE ( t1.f10 ) IN ( SELECT f11 FROM t2 GROUP BY f11 )); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 -2 SUBQUERY eq_ref distinct_key distinct_key 4 func 1 -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE f3 = ( SELECT t1.f3 FROM t1 @@ -729,8 +728,7 @@ WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 )); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 -2 SUBQUERY eq_ref distinct_key distinct_key 8 func,func 1 -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE f3 = ( SELECT f3 FROM t1 @@ -1172,7 +1170,7 @@ WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system PRIMARY NULL NULL NULL 1 1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 -2 DEPENDENT SUBQUERY t1 index_subquery f2 f2 4 func 2 Using index +2 DEPENDENT SUBQUERY t1 index_subquery f2 f2 4 func 1 Using index SELECT t1.f3, MAX(t1.f2) FROM t1, t2 WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1); @@ -1249,7 +1247,7 @@ drop table t1, t2; # CREATE TABLE t1 (c1 varchar(1) DEFAULT NULL); CREATE TABLE t2 (c1 varchar(1) DEFAULT NULL); -INSERT INTO t2 VALUES ('k'), ('d'); +INSERT INTO t2 VALUES ('k'), ('d'),('x'); CREATE TABLE t3 (c1 varchar(1) DEFAULT NULL); INSERT INTO t3 VALUES ('a'), ('b'), ('c'); CREATE TABLE t4 (c1 varchar(1) primary key); @@ -1262,16 +1260,16 @@ EXPLAIN SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1) -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1) +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2); c1 c1 EXPLAIN SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1) -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1) +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2); c1 c1 SET optimizer_switch='materialization=on'; @@ -1279,19 +1277,18 @@ EXPLAIN SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; Start temporary; End temporary +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2); c1 c1 c1 EXPLAIN SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2); id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index; Using join buffer (flat, BNL join) -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2); c1 c1 SET optimizer_switch=@save_optimizer_switch; @@ -2755,12 +2752,21 @@ INSERT INTO t4 VALUES ('w'),('w'),('x'),('x'), (NULL),(NULL); SET @save_join_cache_level=@@join_cache_level; SET join_cache_level=0; +explain select 1 +from t2 join t1 on +('i','w') not in (select t1.v1,t4.v2 from t4,t1,t3 where t3.v2 = t1.v1) LIMIT ROWS EXAMINED 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 +1 PRIMARY t1 index NULL v1 9 NULL 5 Using index +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 Using where +2 MATERIALIZED t1 ref v1 v1 4 test.t3.v2 1 Using index +2 MATERIALIZED t4 ALL NULL NULL NULL NULL 50 select 1 from t2 join t1 on -('i','w') not in (select t1.v1,t4.v2 from t4,t1,t3 where t3.v2 = t1.v1) LIMIT ROWS EXAMINED 500; +('i','w') not in (select t1.v1,t4.v2 from t4,t1,t3 where t3.v2 = t1.v1) LIMIT ROWS EXAMINED 10; 1 Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 3020 rows, which exceeds LIMIT ROWS EXAMINED (500). The query result may be incomplete +Warning 1931 Query execution was interrupted. The query examined at least 14 rows, which exceeds LIMIT ROWS EXAMINED (10). The query result may be incomplete SET join_cache_level= @save_join_cache_level; DROP TABLE t1,t2,t3,t4; # @@ -2790,9 +2796,8 @@ set names 'utf8'; EXPLAIN SELECT * FROM t2 WHERE (t2.a,t2.b) IN (('abc',1), ('def', 2)); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 5 -1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 Using where -2 MATERIALIZED ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key1 key1 4 test.t2.b 1 Using where; FirstMatch(t2) 3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used set names default; set @@in_predicate_conversion_threshold= @save_in_predicate_conversion_threshold; @@ -2902,8 +2907,8 @@ WHERE tn.key1 IN ('1','2','3','4','5','6','7','8','9','10') ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY hist ALL NULL NULL NULL NULL 100 Using where -2 DEPENDENT SUBQUERY tms range PRIMARY PRIMARY 32 NULL 10 Using where; Using index -2 DEPENDENT SUBQUERY tn eq_ref PRIMARY PRIMARY 32 test.tms.key1 1 Using where +2 DEPENDENT SUBQUERY tn range PRIMARY PRIMARY 32 NULL 10 Using index condition; Using where +2 DEPENDENT SUBQUERY tms eq_ref PRIMARY PRIMARY 32 test.tn.key1 1 Using index set optimizer_switch=@tmp_os; drop table t1, t10, t11; # @@ -2922,6 +2927,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "duplicate_removal": { @@ -2931,9 +2937,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -2948,6 +2956,7 @@ ANALYZE "r_loops": 0, "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -2955,9 +2964,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -2970,6 +2981,7 @@ ANALYZE { "query_block": { "select_id": 3, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -2977,9 +2989,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 2, "r_rows": 2, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -3132,10 +3146,9 @@ where b in (select c from t3 group by (select a from t1 where a = 1) in (select d from t4)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t2); Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t2` semi join (`test`.`t3`) where 1 +Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`c` = `test`.`t2`.`b` select b from t2 where b in (select c from t3 group by (select a from t1 where a = 1) in (select d from t4)); diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index 827037c6d5f..5f2a91f8ca2 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -946,7 +946,7 @@ drop table t1, t2; CREATE TABLE t1 (c1 varchar(1) DEFAULT NULL); CREATE TABLE t2 (c1 varchar(1) DEFAULT NULL); -INSERT INTO t2 VALUES ('k'), ('d'); +INSERT INTO t2 VALUES ('k'), ('d'),('x'); CREATE TABLE t3 (c1 varchar(1) DEFAULT NULL); INSERT INTO t3 VALUES ('a'), ('b'), ('c'); CREATE TABLE t4 (c1 varchar(1) primary key); @@ -2284,9 +2284,13 @@ INSERT INTO t4 VALUES SET @save_join_cache_level=@@join_cache_level; SET join_cache_level=0; +explain select 1 +from t2 join t1 on +('i','w') not in (select t1.v1,t4.v2 from t4,t1,t3 where t3.v2 = t1.v1) LIMIT ROWS EXAMINED 10; + select 1 from t2 join t1 on -('i','w') not in (select t1.v1,t4.v2 from t4,t1,t3 where t3.v2 = t1.v1) LIMIT ROWS EXAMINED 500; +('i','w') not in (select t1.v1,t4.v2 from t4,t1,t3 where t3.v2 = t1.v1) LIMIT ROWS EXAMINED 10; SET join_cache_level= @save_join_cache_level; DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/main/subselect_cache.result b/mysql-test/main/subselect_cache.result index 5c2fd3e66fc..10bb54cbb14 100644 --- a/mysql-test/main/subselect_cache.result +++ b/mysql-test/main/subselect_cache.result @@ -49,6 +49,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -56,9 +57,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -73,6 +76,7 @@ ANALYZE "r_hit_ratio": 60, "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 4, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -80,9 +84,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 4, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -106,6 +112,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -113,9 +120,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 10, "r_rows": 10, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -138,6 +147,7 @@ ANALYZE { "query_block": { "select_id": 3, + "cost": "REPLACED", "r_loops": 4, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -145,9 +155,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 4, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -178,6 +190,7 @@ ANALYZE "r_hit_ratio": 60, "query_block": { "select_id": 2, + "cost": "REPLACED", "r_loops": 4, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -185,9 +198,11 @@ ANALYZE "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "r_loops": 4, "rows": 4, "r_rows": 4, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -208,12 +223,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -224,12 +242,15 @@ EXPLAIN "state": "uninitialized", "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t2.c" } @@ -247,12 +268,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -269,12 +293,15 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t2.c" } @@ -301,12 +328,15 @@ EXPLAIN "state": "uninitialized", "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t2", "access_type": "ALL", + "loops": 1, "rows": 4, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "t1.b = t2.c" } diff --git a/mysql-test/main/subselect_cache.test b/mysql-test/main/subselect_cache.test index cf647afb994..7695b01b1ea 100644 --- a/mysql-test/main/subselect_cache.test +++ b/mysql-test/main/subselect_cache.test @@ -34,8 +34,10 @@ select a, (select d from t2 where b=c) from t1; --source include/analyze-format.inc analyze format=json select a, (select d from t2 where b=c), (select d from t2 where b=c union select 1 order by 1 limit 1) from t1; +--source include/explain-no-costs.inc explain format=json select a, (select d from t2 where b=c) from t1; +--source include/explain-no-costs.inc explain format=json select a, (select d from t2 where b=c), (select d from t2 where b=c union select 1 order by 1 limit 1) from t1; set optimizer_switch='subquery_cache=off'; diff --git a/mysql-test/main/subselect_exists2in.result b/mysql-test/main/subselect_exists2in.result index 6ff518b5a29..f6a4365f522 100644 --- a/mysql-test/main/subselect_exists2in.result +++ b/mysql-test/main/subselect_exists2in.result @@ -51,8 +51,8 @@ c explain extended SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t3 WHERE t3.b = t1.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 index aa aa 4 NULL 2 100.00 Using index -1 PRIMARY t3 ALL bb NULL NULL NULL 2 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +1 PRIMARY t1 index aa aa 4 NULL 2 100.00 Using where; Using index +1 PRIMARY t3 ref bb bb 4 test.t1.a 1 100.00 FirstMatch(t1) Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t3`.`b` = `test`.`t1`.`a` @@ -65,10 +65,10 @@ explain extended SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t3 WHERE t3.b = t1.a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL aa 4 NULL 2 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t3 ALL bb NULL NULL NULL 2 100.00 Using where +2 DEPENDENT SUBQUERY t3 index_subquery bb bb 4 func 1 100.00 Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a`,(/* select#2 */ select `test`.`t3`.`b` from `test`.`t3` where (`test`.`t1`.`a`) = `test`.`t3`.`b`)) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a`,(((`test`.`t1`.`a`) in t3 on bb))) -- EXIST2IN then MATERIALIZATION set optimizer_switch='exists_to_in=on,in_to_exists=off,semijoin=off,materialization=on,subquery_cache=off'; SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t3 WHERE t3.b = t1.a); @@ -91,7 +91,7 @@ explain extended SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t3 WHERE t3.b = t1.a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL aa 4 NULL 2 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t3 ALL bb NULL NULL NULL 2 100.00 Using where +2 DEPENDENT SUBQUERY t3 ref bb bb 4 test.t1.a 1 100.00 Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where exists(/* select#2 */ select `test`.`t3`.`a` from `test`.`t3` where `test`.`t3`.`b` = `test`.`t1`.`a` limit 1) @@ -297,23 +297,28 @@ d a b e412 e412 h412 d b a i421 i421 l421 d b b m422 m422 o422 drop table t1, t2, t3; +# +# LP BUG#901835 - incorrect semi-join conversion after exists2in +# CREATE TABLE t1 ( a INT ); -INSERT INTO t1 VALUES (7),(0); +INSERT INTO t1 VALUES (7),(0),(100); CREATE TABLE t2 ( b INT ); -INSERT INTO t2 VALUES (0),(8); +INSERT INTO t2 VALUES (0),(8),(1000),(2000),(3000),(4000),(5000); +insert into t2 select seq from seq_6000_to_6100; SELECT * FROM t1 WHERE EXISTS ( SELECT * FROM t2 WHERE b = a ) OR a > 0; a 7 0 +100 explain extended SELECT * FROM t1 WHERE EXISTS ( SELECT * FROM t2 WHERE b = a ) OR a > 0; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 108 100.00 Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`b` from `test`.`t2` where 1 ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`b`)))) or `test`.`t1`.`a` > 0 @@ -386,7 +391,7 @@ explain extended SELECT * FROM t1 WHERE EXISTS ( SELECT * FROM t3 WHERE t3.b = t1.a and t3.b1 = t1.a1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 index bb bb 8 NULL 2 100.00 Using where; Using index; LooseScan -1 PRIMARY t1 ref aa aa 8 test.t3.b,test.t3.b1 2 100.00 Using index +1 PRIMARY t1 ref aa aa 8 test.t3.b,test.t3.b1 1 50.00 Using index Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 'test.t1.a1' of SELECT #2 was resolved in SELECT #1 @@ -400,7 +405,7 @@ explain extended SELECT * FROM t1 WHERE EXISTS ( SELECT * FROM t3 WHERE t3.b = t1.a and t3.b1 = t1.a1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL aa 8 NULL 2 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t3 index_subquery bb bb 8 func,func 2 100.00 Using index; Using where +2 DEPENDENT SUBQUERY t3 index_subquery bb bb 8 func,func 1 100.00 Using index; Using where Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 'test.t1.a1' of SELECT #2 was resolved in SELECT #1 @@ -428,7 +433,7 @@ explain extended SELECT * FROM t1 WHERE EXISTS ( SELECT * FROM t3 WHERE t3.b = t1.a and t3.b1 = t1.a1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL aa 8 NULL 2 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t3 ref bb bb 8 test.t1.a,test.t1.a1 2 100.00 Using index +2 DEPENDENT SUBQUERY t3 ref bb bb 8 test.t1.a,test.t1.a1 1 100.00 Using index Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 'test.t1.a1' of SELECT #2 was resolved in SELECT #1 @@ -622,7 +627,7 @@ SELECT * FROM t1 AS alias WHERE EXISTS ( SELECT * FROM t1 WHERE a > alias.a AND a = alias.b ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY alias ALL NULL NULL NULL NULL 2 100.00 Using where -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary; End temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 50.00 Using where; Start temporary; End temporary Warnings: Note 1276 Field or reference 'test.alias.a' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 'test.alias.b' of SELECT #2 was resolved in SELECT #1 @@ -713,14 +718,15 @@ set optimizer_switch='exists_to_in=on'; # correct calculation of reserved items (postreview-fix) # create table t1 (col1 int, col2 int, col3 int); -insert into t1 values (1,2,3),(2,3,4),(4,5,6); +insert into t1 values (1,2,3),(2,3,4),(4,5,6),(7,8,9); create table t2 as select * from t1; +insert into t2 select seq,seq,seq from seq_1000_to_1200; explain extended select * from t1 where exists (select col2 from t2 where t2.col1=t1.col1 and t2.col2=t1.col2); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 205 100.00 Warnings: Note 1276 Field or reference 'test.t1.col1' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 'test.t1.col2' of SELECT #2 was resolved in SELECT #1 @@ -730,6 +736,7 @@ col1 col2 col3 1 2 3 2 3 4 4 5 6 +7 8 9 drop table t1,t2; # # MDEV-3879: Exists2In: Wrong result (extra row) and unexpected @@ -902,9 +909,8 @@ WHERE EXISTS ( SELECT * FROM t1 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -3 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 50.00 Using where; FirstMatch 3 DEPENDENT SUBQUERY sq2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) -4 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Warnings: Note 1276 Field or reference 'sq1.pk' of SELECT #3 was resolved in SELECT #1 Note 1276 Field or reference 'sq1.f1' of SELECT #3 was resolved in SELECT #1 @@ -922,9 +928,8 @@ WHERE EXISTS ( SELECT * FROM t1 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -3 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 50.00 Using where; FirstMatch 3 DEPENDENT SUBQUERY sq2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) -4 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Warnings: Note 1276 Field or reference 'sq1.pk' of SELECT #3 was resolved in SELECT #1 Note 1276 Field or reference 'sq1.f1' of SELECT #3 was resolved in SELECT #1 diff --git a/mysql-test/main/subselect_exists2in.test b/mysql-test/main/subselect_exists2in.test index 8ad89be2b65..625c007e006 100644 --- a/mysql-test/main/subselect_exists2in.test +++ b/mysql-test/main/subselect_exists2in.test @@ -1,4 +1,5 @@ --source include/default_optimizer_switch.inc +--source include/have_sequence.inc --disable_warnings drop table if exists t1,t2,t3; @@ -238,13 +239,14 @@ group by a1,a2,b; drop table t1, t2, t3; -# -# LP BUG#901835 - incorrect semi-join conversion after exists2in -# +--echo # +--echo # LP BUG#901835 - incorrect semi-join conversion after exists2in +--echo # CREATE TABLE t1 ( a INT ); -INSERT INTO t1 VALUES (7),(0); +INSERT INTO t1 VALUES (7),(0),(100); CREATE TABLE t2 ( b INT ); -INSERT INTO t2 VALUES (0),(8); +INSERT INTO t2 VALUES (0),(8),(1000),(2000),(3000),(4000),(5000); +insert into t2 select seq from seq_6000_to_6100; SELECT * FROM t1 WHERE EXISTS ( SELECT * FROM t2 WHERE b = a ) @@ -571,8 +573,10 @@ set optimizer_switch='exists_to_in=on'; --echo # correct calculation of reserved items (postreview-fix) --echo # create table t1 (col1 int, col2 int, col3 int); -insert into t1 values (1,2,3),(2,3,4),(4,5,6); +insert into t1 values (1,2,3),(2,3,4),(4,5,6),(7,8,9); create table t2 as select * from t1; +insert into t2 select seq,seq,seq from seq_1000_to_1200; + explain extended select * from t1 where exists (select col2 from t2 where t2.col1=t1.col1 and t2.col2=t1.col2); select * from t1 where exists (select col2 from t2 where t2.col1=t1.col1 and t2.col2=t1.col2); diff --git a/mysql-test/main/subselect_exists2in_costmat.result b/mysql-test/main/subselect_exists2in_costmat.result index 1c9574aafd3..6aecfeafb65 100644 --- a/mysql-test/main/subselect_exists2in_costmat.result +++ b/mysql-test/main/subselect_exists2in_costmat.result @@ -37,8 +37,6 @@ create index Language on CountryLanguage(Language); create index CityName on City(Name); alter table City change population population int(11) null default 0; select max(id) from City into @max_city_id; -Warnings: -Warning 1287 ' INTO FROM...' instead insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL); SELECT COUNT(*) FROM Country; COUNT(*) diff --git a/mysql-test/main/subselect_exists2in_costmat.test b/mysql-test/main/subselect_exists2in_costmat.test index 371f0936d1a..dd3890496f5 100644 --- a/mysql-test/main/subselect_exists2in_costmat.test +++ b/mysql-test/main/subselect_exists2in_costmat.test @@ -67,6 +67,7 @@ set @@optimizer_switch = 'exists_to_in=on,in_to_exists=on,semijoin=on,materializ -- echo Q1.1m: -- echo MATERIALIZATION: there are too many rows in the outer query -- echo to be looked up in the inner table. + EXPLAIN SELECT Name FROM Country WHERE (EXISTS (select 1 from City where City.Population > 100000 and diff --git a/mysql-test/main/subselect_extra.result b/mysql-test/main/subselect_extra.result index c654fdfca13..378e8dafd4b 100644 --- a/mysql-test/main/subselect_extra.result +++ b/mysql-test/main/subselect_extra.result @@ -393,7 +393,7 @@ EXPLAIN SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -1 PRIMARY ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1) +1 PRIMARY ref key0 key0 10 test.t1.a,test.t1.b 1 FirstMatch(t1) 3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort SELECT * FROM v2; a b @@ -451,8 +451,8 @@ WHERE t3.b IN (SELECT v1.b FROM v1, t2 WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 -1 PRIMARY ref key1 key1 8 const,const 0 Start temporary -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY ref key1 key1 8 const,const 0 FirstMatch(t3) 3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where SELECT * FROM t3 WHERE t3.b IN (SELECT v1.b FROM v1, t2 @@ -474,7 +474,7 @@ EXPLAIN SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -1 PRIMARY ref key0 key0 10 test.t1.b,test.t1.a 2 FirstMatch(t1) +1 PRIMARY ref key0 key0 10 test.t1.b,test.t1.a 1 FirstMatch(t1) 3 DERIVED t2 ALL NULL NULL NULL NULL 2 SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a); a b diff --git a/mysql-test/main/subselect_extra_no_semijoin.result b/mysql-test/main/subselect_extra_no_semijoin.result index faeaf75c590..e4d38719ff2 100644 --- a/mysql-test/main/subselect_extra_no_semijoin.result +++ b/mysql-test/main/subselect_extra_no_semijoin.result @@ -395,7 +395,7 @@ EXPLAIN SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY index_subquery key0 key0 10 func,func 2 Using where +2 DEPENDENT SUBQUERY index_subquery key0 key0 10 func,func 1 Using where 3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort SELECT * FROM v2; a b @@ -476,7 +476,7 @@ EXPLAIN SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY ref key0 key0 5 test.t1.a 2 Using where +2 DEPENDENT SUBQUERY ref key0 key0 5 test.t1.a 1 Using where 3 DERIVED t2 ALL NULL NULL NULL NULL 2 SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a); a b diff --git a/mysql-test/main/subselect_innodb.result b/mysql-test/main/subselect_innodb.result index 242b01f8955..2ce0096831b 100644 --- a/mysql-test/main/subselect_innodb.result +++ b/mysql-test/main/subselect_innodb.result @@ -314,7 +314,7 @@ EXPLAIN SELECT 1 FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 1 Using where -2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY,d PRIMARY 1 func 1 Using where +2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY,d d 2 func 1 Using index; Using where 3 DEPENDENT SUBQUERY t2 index NULL d 2 NULL 1 Using index DROP TABLE t2; CREATE TABLE t2 (b INT, c INT, UNIQUE KEY (b), UNIQUE KEY (b, c )) ENGINE=INNODB; @@ -462,7 +462,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT b FROM t2, t3 GROUP BY b HAVING b != 3 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY t2 index NULL PRIMARY 4 NULL 1 Using index; Using temporary +2 SUBQUERY t2 ALL NULL NULL NULL NULL 1 Using temporary 2 SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE EXISTS ( SELECT b FROM t2, t3 GROUP BY b HAVING b != 3 ); a @@ -560,6 +560,7 @@ id select_type table type possible_keys key key_len ref rows Extra # # MDEV-6081: ORDER BY+ref(const): selectivity is very incorrect (MySQL Bug#14338686) # +insert into t2 select seq,seq,seq from seq_10000_to_11000; alter table t2 add key2 int; update t2 set key2=key1; alter table t2 add key(key2); @@ -580,6 +581,29 @@ t1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL # 2 DEPENDENT SUBQUERY t2 ref key1 key1 5 test.t1.a # Using where; Using filesort +select +(SELECT +concat(id, '-', key1, '-', col1) +FROM t2 +WHERE t2.key1 = t1.a +ORDER BY t2.key2 ASC LIMIT 1) +from +t1; +(SELECT +concat(id, '-', key1, '-', col1) +FROM t2 +WHERE t2.key1 = t1.a +ORDER BY t2.key2 ASC LIMIT 1) +100-0-123456 +101-1-123456 +102-2-123456 +103-3-123456 +104-4-123456 +105-5-123456 +106-6-123456 +107-7-123456 +108-8-123456 +109-9-123456 drop table t1,t2; # # MDEV-12931: semi-join in ON expression of STRAIGHT_JOIN @@ -612,11 +636,10 @@ INNER JOIN ON ( 1 IN ( SELECT f4 FROM t4 ) ) ) ON ( f1 >= f2 ); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 50.00 Using where; FirstMatch 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (incremental, BNL join) -3 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` semi join (`test`.`t4`) join `test`.`t3` where `test`.`t4`.`f4` = 1 and `test`.`t1`.`f1` >= `test`.`t2`.`f2` DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/main/subselect_innodb.test b/mysql-test/main/subselect_innodb.test index e354ddc4496..c1dd58887b0 100644 --- a/mysql-test/main/subselect_innodb.test +++ b/mysql-test/main/subselect_innodb.test @@ -1,5 +1,6 @@ -- source include/no_valgrind_without_big.inc -- source include/have_innodb.inc +-- source include/have_sequence.inc # Note: the tests uses only non-semijoin subqueries so semi-join switch # settings are not relevant. @@ -568,6 +569,11 @@ from --echo # MDEV-6081: ORDER BY+ref(const): selectivity is very incorrect (MySQL Bug#14338686) --echo # + +# Table t2 has 100 equal values / key value, which causes it to prefer index scan instead of ref +# Fix it by adding more different values to key1 +insert into t2 select seq,seq,seq from seq_10000_to_11000; + alter table t2 add key2 int; update t2 set key2=key1; alter table t2 add key(key2); @@ -583,6 +589,14 @@ explain select ORDER BY t2.key2 ASC LIMIT 1) from t1; +select + (SELECT + concat(id, '-', key1, '-', col1) + FROM t2 + WHERE t2.key1 = t1.a + ORDER BY t2.key2 ASC LIMIT 1) +from + t1; drop table t1,t2; diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result index 25465fe650a..3d7f6d601b6 100644 --- a/mysql-test/main/subselect_mat.result +++ b/mysql-test/main/subselect_mat.result @@ -1142,7 +1142,7 @@ a explain extended select a from t1 group by a having a in (select c from t2 where d >= 20); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 range NULL it1a 4 NULL 8 100.00 Using index for group-by +1 PRIMARY t1 range NULL it1a 4 NULL 7 100.00 Using index for group-by 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`c`)))) @@ -1154,7 +1154,7 @@ create index iab on t1(a, b); explain extended select a from t1 group by a having a in (select c from t2 where d >= 20); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 range NULL it1a 4 NULL 8 100.00 Using index for group-by +1 PRIMARY t1 range NULL it1a 4 NULL 7 100.00 Using index for group-by 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`c`)))) @@ -1166,7 +1166,7 @@ explain extended select a from t1 group by a having a in (select c from t2 where d >= some(select e from t3 where max(b)=e)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 range NULL iab 4 NULL 8 100.00 Using index for group-by +1 PRIMARY t1 range NULL iab 4 NULL 7 100.00 Using index for group-by 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where 3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where Warnings: @@ -1510,13 +1510,15 @@ SET @@optimizer_switch='semijoin=on,materialization=on'; EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 7 func,func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2); COUNT(*) 2 set @@optimizer_switch= @local_optimizer_switch; DROP TABLE t1, t2; +# +# BUG#46548 IN-subqueries return 0 rows with materialization=on +# CREATE TABLE t1 ( pk int, a varchar(1), @@ -1526,16 +1528,19 @@ d varchar(4), PRIMARY KEY (pk) ); INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff'); +insert into t1 select seq,'x','xxxx','xxxx','xxxx' from seq_10_to_40; CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); +insert into t2 select -seq,'a','aaaa','aaaa','aaaa' from seq_1_to_20; +insert into t2 select seq,'b','bbbb','bbbb','bbbb' from seq_100_to_200; set @local_optimizer_switch=@@optimizer_switch; set @@optimizer_switch=@optimizer_switch_local_default; SET @@optimizer_switch='semijoin=on,materialization=on'; EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 33 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan +2 MATERIALIZED t2 ALL PRIMARY NULL NULL NULL 123 Using where SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); pk 2 @@ -1890,19 +1895,20 @@ WHERE alias4.c = alias3.b id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 3 MATERIALIZED alias3 ALL NULL NULL NULL NULL 2 Using where -3 MATERIALIZED alias4 ref c c 11 test.alias3.b 2 Using where; Using index +3 MATERIALIZED alias4 ref c c 11 test.alias3.b 1 Using where; Using index DROP TABLE t1,t2; # # BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result # create table t1 (a int, b int); insert into t1 values (7,5), (3,3), (5,4), (9,3); +insert into t1 select seq,seq from seq_100_to_200; create table t2 (a int, b int, index i_a(a)); insert into t2 values (4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1); explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 105 Using where 2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); a b @@ -1953,11 +1959,11 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 Using where 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = ``.`MAX(c)` and ((/*always not null*/ 1 is null) or ``.`MAX(c)` = 7) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and ``.`MAX(c)` = `test`.`t1`.`a` and (`test`.`t1`.`a` is null or `test`.`t1`.`a` = 7) SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); a b @@ -1966,8 +1972,8 @@ EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY const distinct_key distinct_key 4 const 1 -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY const distinct_key distinct_key 4 const 1 Using where 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); @@ -2194,9 +2200,8 @@ mysqltest1 EXPLAIN EXTENDED SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 100.00 Using temporary; Using filesort -1 PRIMARY t1 eq_ref db db 764 information_schema.schemata.SCHEMA_NAME 1 100.00 Using where; Using index -2 MATERIALIZED schemata ALL NULL NULL NULL NULL NULL NULL +1 PRIMARY t1 index db db 764 NULL 4 100.00 Using index; Using temporary; Using filesort +1 PRIMARY schemata ALL NULL NULL NULL NULL NULL NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`db` AS `db` from `test`.`t1` semi join (`information_schema`.`schemata`) where `test`.`t1`.`db` = `information_schema`.`schemata`.`SCHEMA_NAME` order by `test`.`t1`.`db` desc drop table t1; @@ -2228,8 +2233,10 @@ drop table t1; CREATE TABLE t1 ( pk INT, f1 INT NOT NULL, f2 VARCHAR(3), f3 INT NULL, PRIMARY KEY(pk)) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,1,'foo',8), (2,5,'bar',7); +create table t2 like t1; +insert into t2 select * from t1; SELECT sq1.f2 FROM t1 AS sq1 -WHERE EXISTS ( SELECT * FROM t1 AS sq2 +WHERE EXISTS ( SELECT * FROM t2 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); f2 foo @@ -2241,18 +2248,17 @@ WHERE EXISTS ( SELECT * FROM t1 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY sq1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where; FirstMatch 2 DEPENDENT SUBQUERY sq2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 # this checks the result set above set optimizer_switch= 'materialization=off,semijoin=off'; SELECT sq1.f2 FROM t1 AS sq1 -WHERE EXISTS ( SELECT * FROM t1 AS sq2 +WHERE EXISTS ( SELECT * FROM t2 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); f2 foo set optimizer_switch= @local_optimizer_switch; -DROP TABLE t1; +DROP TABLE t1,t2; # # MDEV-12145: IN subquery used in WHERE of EXISTS subquery # @@ -2275,10 +2281,9 @@ WHERE EXISTS ( SELECT * FROM t2, t3 WHERE i3 = i2 AND f1 IN ( SELECT f3 FROM t3 ) ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 8 12.50 Using where; FirstMatch 2 DEPENDENT SUBQUERY t2 range i2 i2 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY t3 ref i3 i3 5 test.t2.i2 2 100.00 Using index -3 MATERIALIZED t3 ALL NULL NULL NULL NULL 8 100.00 +2 DEPENDENT SUBQUERY t3 ref i3 i3 5 test.t2.i2 1 100.00 Using index Warnings: Note 1276 Field or reference 'test.t1.f1' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where <`test`.`t1`.`f1`>(exists(/* select#2 */ select 1 from `test`.`t2` semi join (`test`.`t3`) join `test`.`t3` where `test`.`t3`.`i3` = `test`.`t2`.`i2` and `test`.`t1`.`f1` = `test`.`t3`.`f3` limit 1)) @@ -2314,9 +2319,8 @@ SELECT pk, f1, ( SELECT COUNT(*) FROM t2 WHERE t1.pk IN ( SELECT f2 FROM t2 ) ) AS sq FROM t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00 -2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 20.00 Using where; FirstMatch 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using join buffer (flat, BNL join) -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Warnings: Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`f1` AS `f1`,<`test`.`t1`.`pk`>((/* select#2 */ select count(0) from `test`.`t2` semi join (`test`.`t2`) where `test`.`t1`.`pk` = `test`.`t2`.`f2`)) AS `sq` from `test`.`t1` @@ -2399,11 +2403,10 @@ WHERE t2.ugroup = t3_i.sys_id AND t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND t2.user = '86826bf03710200044e0bfc8bcbe5d79'); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where +1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary +1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where +1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index -2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where -2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where set statement optimizer_prune_level=1 for explain SELECT t1.assignment_group FROM t1, t3 WHERE t1.assignment_group = t3.sys_id AND @@ -2414,11 +2417,10 @@ WHERE t2.ugroup = t3_i.sys_id AND t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND t2.user = '86826bf03710200044e0bfc8bcbe5d79'); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where +1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary +1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where +1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index -3 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where -3 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where SELECT t1.assignment_group FROM t1, t3 WHERE t1.assignment_group = t3.sys_id AND @@ -2450,8 +2452,7 @@ explain SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); 1 1 @@ -2463,8 +2464,7 @@ explain SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index id id 4 NULL 9 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); 1 1 @@ -2513,20 +2513,17 @@ drop procedure prepare_data; set @@optimizer_switch= @local_optimizer_switch; drop table t1,t2,t3; CREATE TABLE t1 ( id int NOT NULL, key(id)); -INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +INSERT INTO t1 select seq from seq_11_to_39; CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); -INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +INSERT INTO t2 select seq,seq+1 from seq_11_to_50; CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index id id 4 NULL 9 Using index +1 PRIMARY t1 index id id 4 NULL 29 Using index 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 40 Using where SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); 1 -1 -1 -1 drop table t1,t2; drop view v1; # @@ -2817,12 +2814,12 @@ PRIMARY KEY (pk) INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff'); CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); +insert into t2 select -seq,"","","","" from seq_1_to_10; SET @@optimizer_switch='default,semijoin=on,materialization=on'; EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); pk 2 diff --git a/mysql-test/main/subselect_mat.test b/mysql-test/main/subselect_mat.test index cacafb0000f..58548d18caa 100644 --- a/mysql-test/main/subselect_mat.test +++ b/mysql-test/main/subselect_mat.test @@ -2,7 +2,7 @@ # Hash semi-join regression tests # (WL#1110: Subquery optimization: materialization) # - +--source include/have_sequence.inc # force the use of materialization set @subselect_mat_test_optimizer_switch_value='materialization=on,in_to_exists=off,semijoin=off'; @@ -111,6 +111,7 @@ INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff'); CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); +insert into t2 select -seq,"","","","" from seq_1_to_10; SET @@optimizer_switch='default,semijoin=on,materialization=on'; EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); diff --git a/mysql-test/main/subselect_mat_cost-master.opt b/mysql-test/main/subselect_mat_cost.opt similarity index 100% rename from mysql-test/main/subselect_mat_cost-master.opt rename to mysql-test/main/subselect_mat_cost.opt diff --git a/mysql-test/main/subselect_mat_cost.result b/mysql-test/main/subselect_mat_cost.result index 66d48b549c4..240332f3c5b 100644 --- a/mysql-test/main/subselect_mat_cost.result +++ b/mysql-test/main/subselect_mat_cost.result @@ -39,8 +39,6 @@ create index Language on CountryLanguage(Language); create index CityName on City(Name); alter table City change population population int(11) null default 0; select max(id) from City into @max_city_id; -Warnings: -Warning 1287 ' INTO FROM...' instead insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL); SELECT COUNT(*) FROM Country; COUNT(*) @@ -60,47 +58,19 @@ Q1.1m: MATERIALIZATION: there are too many rows in the outer query to be looked up in the inner table. EXPLAIN -SELECT Name FROM Country +SELECT count(*) FROM Country WHERE (Code IN (select Country from City where City.Population > 100000) OR Name LIKE 'L%') AND -surfacearea > 1000000; +surfacearea > 100000; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY Country ALL Name,SurfaceArea NULL NULL NULL 239 Using where 2 MATERIALIZED City ALL Population,Country NULL NULL NULL 4079 Using where -SELECT Name FROM Country +SELECT count(*) FROM Country WHERE (Code IN (select Country from City where City.Population > 100000) OR Name LIKE 'L%') AND -surfacearea > 1000000; -Name -Algeria -Angola -Argentina -Australia -Bolivia -Brazil -Egypt -South Africa -Ethiopia -Indonesia -India -Iran -Canada -Kazakstan -China -Colombia -Congo, The Democratic Republic of the -Libyan Arab Jamahiriya -Mali -Mauritania -Mexico -Mongolia -Niger -Peru -Saudi Arabia -Sudan -Chad -Russian Federation -United States +surfacearea > 100000; +count(*) +107 Q1.1e: IN-EXISTS: the materialization cost is the same as above, but there are much fewer outer rows to be looked up, thus the @@ -136,10 +106,22 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where 1 PRIMARY City ref Country Country 3 world.Country.Code 17 Using where 2 MATERIALIZED CountryLanguage ALL Percentage,Language NULL NULL NULL 984 Using where +EXPLAIN SELECT * FROM Country, City WHERE City.Country = Country.Code AND -Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND +Country.SurfaceArea < 500 AND Country.SurfaceArea > 10 AND +(City.Name IN +(select Language from CountryLanguage where Percentage > 50) OR +City.name LIKE '%Island%'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY Country range PRIMARY,SurfaceArea SurfaceArea 4 NULL 32 Using index condition; Rowid-ordered scan +1 PRIMARY City ref Country Country 3 world.Country.Code 17 Using where +2 MATERIALIZED CountryLanguage ALL Percentage,Language NULL NULL NULL 984 Using where +SELECT * +FROM Country, City +WHERE City.Country = Country.Code AND +Country.SurfaceArea < 500 AND Country.SurfaceArea > 10 AND (City.Name IN (select Language from CountryLanguage where Percentage > 50) OR City.name LIKE '%Island%'); @@ -515,9 +497,30 @@ FROM City JOIN Country ON City.Country = Country.Code GROUP BY City.Name HAVING City.Name IN (select Name from Country where population < 1000000); id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY City ALL Country NULL NULL NULL 4079 Using temporary; Using filesort +1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using index +2 MATERIALIZED Country ALL Name NULL NULL NULL 239 Using where +Last_query_cost 5.934845 +EXPLAIN +SELECT straight_join City.Name, City.Population +FROM Country JOIN City ON City.Country = Country.Code +GROUP BY City.Name +HAVING City.Name IN (select Name from Country where population < 1000000); +id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY Country index PRIMARY PRIMARY 3 NULL 239 Using index; Using temporary; Using filesort 1 PRIMARY City ref Country Country 3 world.Country.Code 17 2 MATERIALIZED Country ALL Name NULL NULL NULL 239 Using where +Last_query_cost 7.972882 +EXPLAIN +SELECT City.Name, City.Population +FROM Country LEFT JOIN City ON City.Country = Country.Code +GROUP BY City.Name +HAVING City.Name IN (select Name from Country where population < 1000000); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY Country index NULL PRIMARY 3 NULL 239 Using index; Using temporary; Using filesort +1 PRIMARY City ref Country Country 3 world.Country.Code 17 +2 MATERIALIZED Country ALL Name NULL NULL NULL 239 Using where +Last_query_cost 7.972882 SELECT City.Name, City.Population FROM City JOIN Country ON City.Country = Country.Code GROUP BY City.Name diff --git a/mysql-test/main/subselect_mat_cost.test b/mysql-test/main/subselect_mat_cost.test index 8fe38849735..60763076c45 100644 --- a/mysql-test/main/subselect_mat_cost.test +++ b/mysql-test/main/subselect_mat_cost.test @@ -74,15 +74,15 @@ set @@optimizer_switch = 'in_to_exists=on,semijoin=on,materialization=on,partial -- echo MATERIALIZATION: there are too many rows in the outer query -- echo to be looked up in the inner table. EXPLAIN -SELECT Name FROM Country +SELECT count(*) FROM Country WHERE (Code IN (select Country from City where City.Population > 100000) OR Name LIKE 'L%') AND - surfacearea > 1000000; + surfacearea > 100000; -SELECT Name FROM Country +SELECT count(*) FROM Country WHERE (Code IN (select Country from City where City.Population > 100000) OR Name LIKE 'L%') AND - surfacearea > 1000000; + surfacearea > 100000; -- echo Q1.1e: -- echo IN-EXISTS: the materialization cost is the same as above, but @@ -113,10 +113,19 @@ SELECT * (select Language from CountryLanguage where Percentage > 50) OR City.name LIKE '%Island%'); +EXPLAIN SELECT * FROM Country, City WHERE City.Country = Country.Code AND - Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND + Country.SurfaceArea < 500 AND Country.SurfaceArea > 10 AND + (City.Name IN + (select Language from CountryLanguage where Percentage > 50) OR + City.name LIKE '%Island%'); + +SELECT * + FROM Country, City + WHERE City.Country = Country.Code AND + Country.SurfaceArea < 500 AND Country.SurfaceArea > 10 AND (City.Name IN (select Language from CountryLanguage where Percentage > 50) OR City.name LIKE '%Island%'); @@ -210,7 +219,6 @@ WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English -- echo MATERIALIZATION because the outer query filters less rows than Q5-a, -- echo so there are more lookups. - set statement optimizer_switch='rowid_filter=off' for EXPLAIN SELECT Country.Name @@ -369,18 +377,33 @@ drop index CountryCapital on Country; # TODO: the cost estimates for subqueries in the HAVING clause need to be changed # to take into account that the subquery predicate is executed #times ~ to the # number of groups, not number of rows + EXPLAIN SELECT City.Name, City.Population FROM City JOIN Country ON City.Country = Country.Code GROUP BY City.Name HAVING City.Name IN (select Name from Country where population < 1000000); +--source include/last_query_cost.inc + +EXPLAIN +SELECT straight_join City.Name, City.Population +FROM Country JOIN City ON City.Country = Country.Code +GROUP BY City.Name +HAVING City.Name IN (select Name from Country where population < 1000000); +--source include/last_query_cost.inc + +EXPLAIN +SELECT City.Name, City.Population +FROM Country LEFT JOIN City ON City.Country = Country.Code +GROUP BY City.Name +HAVING City.Name IN (select Name from Country where population < 1000000); +--source include/last_query_cost.inc SELECT City.Name, City.Population FROM City JOIN Country ON City.Country = Country.Code GROUP BY City.Name HAVING City.Name IN (select Name from Country where population < 1000000); - -- echo -- echo 5. Subqueries with UNION -- echo diff --git a/mysql-test/main/subselect_mat_cost_bugs.result b/mysql-test/main/subselect_mat_cost_bugs.result index 1889291398c..77b3430ba1f 100644 --- a/mysql-test/main/subselect_mat_cost_bugs.result +++ b/mysql-test/main/subselect_mat_cost_bugs.result @@ -95,9 +95,9 @@ t1a ON (t1a.c2 = t1b.pk AND 2) WHERE t1.pk) ; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 100.00 Using where -2 DEPENDENT SUBQUERY t1b ALL NULL NULL NULL NULL 9 100.00 +2 DEPENDENT SUBQUERY t1b ALL NULL NULL NULL NULL 9 100.00 Using where 2 DEPENDENT SUBQUERY t1a ref c2 c2 5 test.t1b.pk 1 100.00 Using where -2 DEPENDENT SUBQUERY t2 index c3 c3 9 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t2 ref c3 c3 4 test.t1b.c4 1 100.00 Using index Warnings: Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where <`test`.`t1`.`c1`,`test`.`t1`.`pk`>((`test`.`t1`.`c1`,(/* select#2 */ select `test`.`t1a`.`c1` from `test`.`t1b` join `test`.`t2` left join `test`.`t1a` on(`test`.`t1a`.`c2` = `test`.`t1b`.`pk` and 2) where `test`.`t2`.`c3` = `test`.`t1b`.`c4` and `test`.`t1`.`pk` <> 0 and (`test`.`t1`.`c1`) = `test`.`t1a`.`c1`))) @@ -263,8 +263,8 @@ WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED alias1 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY alias1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) SELECT * FROM t2 WHERE ( f12 ) IN ( SELECT alias2.f3 @@ -275,6 +275,8 @@ f12 f13 Warnings: Warning 1292 Truncated incorrect DECIMAL value: 'f' Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1292 Truncated incorrect DECIMAL value: 'd' EXPLAIN SELECT * FROM t2 WHERE ( f12 ) IN ( @@ -283,8 +285,8 @@ FROM t1 AS alias1, t1 AS alias2 WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED alias1 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY alias1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) SELECT * FROM t2 WHERE ( f12 ) IN ( SELECT alias2.f3 @@ -294,6 +296,8 @@ f12 f13 Warnings: Warning 1292 Truncated incorrect DECIMAL value: 'f' Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1292 Truncated incorrect DECIMAL value: 'd' set @@optimizer_switch=@save_optimizer_switch; drop table t1, t2; # @@ -316,7 +320,7 @@ explain select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY t2 ref key1,key2,key3 key3 5 const 1 Using where +2 DEPENDENT SUBQUERY t2 index_subquery key1,key2,key3 key1 10 func,const 1 Using where select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7; c1 set @@optimizer_switch='default'; diff --git a/mysql-test/main/subselect_no_exists_to_in.result b/mysql-test/main/subselect_no_exists_to_in.result index e32e6007328..3a144e70c75 100644 --- a/mysql-test/main/subselect_no_exists_to_in.result +++ b/mysql-test/main/subselect_no_exists_to_in.result @@ -899,6 +899,9 @@ select (select a+1) from t1; NULL 4.5 drop table t1; +# +# Null with keys +# CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a)); CREATE TABLE t2 (a int(11) default '0', INDEX (a)); INSERT INTO t1 VALUES (1),(2),(3),(4); @@ -1430,6 +1433,9 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); a 1 +# +# IN subselect optimization test +# create table t1 (a int not null, b int, primary key (a)); create table t2 (a int not null, primary key (a)); create table t3 (a int not null, b int, primary key (a)); @@ -1453,21 +1459,21 @@ a 4 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using where +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 3 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 -1 PRIMARY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where `test`.`t3`.`a` = `test`.`t1`.`b` and `test`.`t1`.`a` = `test`.`t2`.`a` +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where `test`.`t3`.`a` = `test`.`t1`.`b` and `test`.`t2`.`a` = `test`.`t1`.`a` drop table t1, t2, t3; create table t1 (a int, b int, index a (a,b)); create table t2 (a int, index a (a)); @@ -1476,42 +1482,48 @@ insert into t1 values (1,10), (2,20), (3,30), (4,40); create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 -select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D; +select rand()*100000+200,rand(1)*100000 from t0 A, t0 B, t0 C, t0 D; insert into t2 values (2), (3), (4), (5); insert into t3 values (10,3), (20,4), (30,5); +explain extended select * from t2 where t2.a in (select a from t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using index; FirstMatch(t2) +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` select * from t2 where t2.a in (select a from t1); a 2 3 4 -explain extended select * from t2 where t2.a in (select a from t1); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2) +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using where; Using index; FirstMatch(t2) Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2) -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 -select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); -a -2 -3 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index 1 PRIMARY t3 range a a 5 NULL 3 100.00 Using where; Using index -1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2) +1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 0.29 Using index; FirstMatch(t2) Warnings: Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where `test`.`t1`.`b` = `test`.`t3`.`a` and `test`.`t1`.`a` = `test`.`t2`.`a` +select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +a +2 +3 insert into t1 values (3,31); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using where; Using index; FirstMatch(t2) +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 @@ -1521,12 +1533,6 @@ select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31 a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2) -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 drop table t0, t1, t2, t3; create table t1 (a int, b int); create table t2 (a int, b int); @@ -1588,6 +1594,9 @@ Note 1003 (select 'tttt' AS `s1` from dual) s1 tttt drop table t1; +# +# IN optimisation test results +# create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); @@ -2421,19 +2430,22 @@ a 1 3 DROP TABLE t1; +# +# SELECT(EXISTS * ...)optimisation +# create table t1 (a int, b int); -insert into t1 values (1,2),(3,4); -select * from t1 up where exists (select * from t1 where t1.a=up.a); -a b -1 2 -3 4 -explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a); +insert into t1 values (1,2),(3,4),(5,6),(7,8); +insert into t1 select seq,seq from seq_20_to_40; +select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); +sum(a+b) +1296 +explain extended select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY up ALL NULL NULL NULL NULL 25 100.00 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 25 100.00 Using where Warnings: Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <`test`.`up`.`a`>(exists(/* select#2 */ select 1 from `test`.`t1` where `test`.`t1`.`a` = `test`.`up`.`a` limit 1)) +Note 1003 /* select#1 */ select sum(`test`.`up`.`a` + `test`.`up`.`b`) AS `sum(a+b)` from `test`.`t1` `up` where <`test`.`up`.`a`>(exists(/* select#2 */ select 1 from `test`.`t1` where `test`.`t1`.`a` = `test`.`up`.`a` limit 1)) drop table t1; CREATE TABLE t1 (t1_a int); INSERT INTO t1 VALUES (1); @@ -3101,9 +3113,13 @@ retailerID statusID changed 0048 1 2006-01-06 12:37:50 0059 1 2006-01-06 12:37:50 drop table t1; +# +# Bug#21180 Subselect with index for both WHERE and ORDER BY +# produces empty result +# create table t1(a int, primary key (a)); insert into t1 values (10); -create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +create table t2 (a int primary key, b varchar(32), c int, unique key cb(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); analyze table t1; @@ -3116,7 +3132,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using where +2 SUBQUERY t2 range cb cb 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3128,7 +3144,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using index condition +2 SUBQUERY t2 range cb cb 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -4228,8 +4244,8 @@ INSERT INTO t2 VALUES (7), (5), (1), (3); SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); id st -3 FL 1 GA +3 FL 7 FL SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) @@ -4330,6 +4346,9 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; 0 0 DROP TABLE t1, t2; +# +# Bug#28076 inconsistent binary/varbinary comparison +# CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)); INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43); SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1); @@ -4391,8 +4410,8 @@ CREATE INDEX I1 ON t1 (a); CREATE INDEX I2 ON t1 (b); EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1) +1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using index condition SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); a b CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10)); @@ -4401,15 +4420,15 @@ CREATE INDEX I1 ON t2 (a); CREATE INDEX I2 ON t2 (b); EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t2 ref I1 I1 4 test.t2.b 2 Using where; Using index; FirstMatch(t2) +1 PRIMARY t2 index I1 I1 4 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t2 ref I2 I2 13 test.t2.a 1 Using index condition SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); a b EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1) +1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using index condition SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); a b DROP TABLE t1,t2; @@ -4439,10 +4458,13 @@ out_a MIN(b) 1 2 2 4 DROP TABLE t1; +# +# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +# CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); -INSERT INTO t1 VALUES (1),(2); -INSERT INTO t2 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1),(2),(1000); SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); 2 2 @@ -4450,8 +4472,8 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select 2 AS `2` from `test`.`t1` where <`test`.`t1`.`a`>(exists(/* select#2 */ select 1 from `test`.`t2` where `test`.`t1`.`a` = `test`.`t2`.`a` limit 1)) @@ -4459,9 +4481,9 @@ EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 3 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 @@ -5700,7 +5722,8 @@ DROP TABLE IF EXISTS ot1, ot4, it2, it3; CREATE TABLE t1 (a int) ; INSERT INTO t1 VALUES (NULL), (1), (NULL), (2); CREATE TABLE t2 (a int, INDEX idx(a)) ; -INSERT INTO t2 VALUES (NULL), (1), (NULL); +INSERT INTO t2 VALUES (NULL), (1), (NULL),(1000); +insert into t2 select seq from seq_3_to_500; SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a); a @@ -5710,7 +5733,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 502 Using where SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); a @@ -5720,7 +5743,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index +2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 58 Using index DROP TABLE t1,t2; # # BUG#752992: Wrong results for a subquery with 'semijoin=on' @@ -5737,9 +5760,9 @@ SET @save_join_cache_level=@@join_cache_level; SET join_cache_level=0; EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3 -1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index -1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(it) +1 PRIMARY it index PRIMARY PRIMARY 4 NULL 3 Using index +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.it.pk 1 +1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(t1) SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); pk i 11 0 @@ -6080,8 +6103,7 @@ WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index +1 PRIMARY it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index; FirstMatch(ot) SELECT col_int_nokey FROM ot WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); @@ -6093,8 +6115,7 @@ WHERE (col_varchar_nokey, 'x') IN (SELECT col_varchar_key, col_varchar_key2 FROM it2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index +1 PRIMARY it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index; FirstMatch(ot) SELECT col_int_nokey FROM ot WHERE (col_varchar_nokey, 'x') IN (SELECT col_varchar_key, col_varchar_key2 FROM it2); @@ -6638,7 +6659,7 @@ SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquer EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 1 Using index SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); a 2009-01-01 @@ -6841,7 +6862,7 @@ FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 WHERE alias1.a = alias2.a OR ('Moscow') IN ( SELECT a FROM t1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY alias1 index a a 19 NULL 11 Using where; Using index -1 PRIMARY alias2 ref a a 19 test.alias1.a 2 Using index +1 PRIMARY alias2 ref a a 19 test.alias1.a 1 Using index 1 PRIMARY alias3 index NULL a 19 NULL 11 Using index; Using join buffer (flat, BNL join) 2 SUBQUERY t1 index_subquery a a 19 const 1 Using index; Using where SELECT MAX( alias2.a ) @@ -6992,7 +7013,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index +1 PRIMARY t3 ref d d 5 test.t2.b 1 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; @@ -7024,7 +7045,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields @@ -7058,7 +7079,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-5991: crash in Item_field::used_tables diff --git a/mysql-test/main/subselect_no_mat.result b/mysql-test/main/subselect_no_mat.result index 07755a5144a..12c72545f73 100644 --- a/mysql-test/main/subselect_no_mat.result +++ b/mysql-test/main/subselect_no_mat.result @@ -352,7 +352,7 @@ patient_uq clinic_uq explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index -1 PRIMARY t6 ALL i1 NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t6 ref i1 i1 5 test.t7.uq 1 100.00 Warnings: Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t7` join `test`.`t6` where `test`.`t6`.`clinic_uq` = `test`.`t7`.`uq` @@ -902,6 +902,9 @@ select (select a+1) from t1; NULL 4.5 drop table t1; +# +# Null with keys +# CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a)); CREATE TABLE t2 (a int(11) default '0', INDEX (a)); INSERT INTO t1 VALUES (1),(2),(3),(4); @@ -1433,6 +1436,9 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); a 1 +# +# IN subselect optimization test +# create table t1 (a int not null, b int, primary key (a)); create table t2 (a int not null, primary key (a)); create table t3 (a int not null, b int, primary key (a)); @@ -1456,21 +1462,21 @@ a 4 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using where +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 3 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 -1 PRIMARY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where `test`.`t3`.`a` = `test`.`t1`.`b` and `test`.`t1`.`a` = `test`.`t2`.`a` +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where `test`.`t3`.`a` = `test`.`t1`.`b` and `test`.`t2`.`a` = `test`.`t1`.`a` drop table t1, t2, t3; create table t1 (a int, b int, index a (a,b)); create table t2 (a int, index a (a)); @@ -1479,42 +1485,48 @@ insert into t1 values (1,10), (2,20), (3,30), (4,40); create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 -select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D; +select rand()*100000+200,rand(1)*100000 from t0 A, t0 B, t0 C, t0 D; insert into t2 values (2), (3), (4), (5); insert into t3 values (10,3), (20,4), (30,5); +explain extended select * from t2 where t2.a in (select a from t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using index; FirstMatch(t2) +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` select * from t2 where t2.a in (select a from t1); a 2 3 4 -explain extended select * from t2 where t2.a in (select a from t1); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2) +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using where; Using index; FirstMatch(t2) Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2) -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 -select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); -a -2 -3 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index 1 PRIMARY t3 range a a 5 NULL 3 100.00 Using where; Using index -1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2) +1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 0.29 Using index; FirstMatch(t2) Warnings: Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where `test`.`t1`.`b` = `test`.`t3`.`a` and `test`.`t1`.`a` = `test`.`t2`.`a` +select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +a +2 +3 insert into t1 values (3,31); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using where; Using index; FirstMatch(t2) +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 @@ -1524,12 +1536,6 @@ select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31 a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2) -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 drop table t0, t1, t2, t3; create table t1 (a int, b int); create table t2 (a int, b int); @@ -1591,6 +1597,9 @@ Note 1003 (select 'tttt' AS `s1` from dual) s1 tttt drop table t1; +# +# IN optimisation test results +# create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); @@ -2424,19 +2433,22 @@ a 1 3 DROP TABLE t1; +# +# SELECT(EXISTS * ...)optimisation +# create table t1 (a int, b int); -insert into t1 values (1,2),(3,4); -select * from t1 up where exists (select * from t1 where t1.a=up.a); -a b -1 2 -3 4 -explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a); +insert into t1 values (1,2),(3,4),(5,6),(7,8); +insert into t1 select seq,seq from seq_20_to_40; +select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); +sum(a+b) +1296 +explain extended select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(up); Using join buffer (flat, BNL join) +1 PRIMARY up ALL NULL NULL NULL NULL 25 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 25 100.00 Using where; FirstMatch(up); Using join buffer (flat, BNL join) Warnings: Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`up`.`a` +Note 1003 select sum(`test`.`up`.`a` + `test`.`up`.`b`) AS `sum(a+b)` from `test`.`t1` `up` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`up`.`a` drop table t1; CREATE TABLE t1 (t1_a int); INSERT INTO t1 VALUES (1); @@ -2987,7 +2999,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 -1 PRIMARY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; FirstMatch(t1) +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 11.11 Using where; Start temporary; End temporary Warnings: Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`flag` = 'N' and `test`.`t2`.`one` = `test`.`t1`.`one` and `test`.`t2`.`two` = `test`.`t1`.`two` explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1; @@ -3103,9 +3115,13 @@ retailerID statusID changed 0048 1 2006-01-06 12:37:50 0059 1 2006-01-06 12:37:50 drop table t1; +# +# Bug#21180 Subselect with index for both WHERE and ORDER BY +# produces empty result +# create table t1(a int, primary key (a)); insert into t1 values (10); -create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +create table t2 (a int primary key, b varchar(32), c int, unique key cb(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); analyze table t1; @@ -3118,7 +3134,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using where +2 SUBQUERY t2 range cb cb 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3130,7 +3146,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using index condition +2 SUBQUERY t2 range cb cb 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -4228,8 +4244,8 @@ INSERT INTO t2 VALUES (7), (5), (1), (3); SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); id st -3 FL 1 GA +3 FL 7 FL SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) @@ -4330,6 +4346,9 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; 0 0 DROP TABLE t1, t2; +# +# Bug#28076 inconsistent binary/varbinary comparison +# CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)); INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43); SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1); @@ -4391,8 +4410,8 @@ CREATE INDEX I1 ON t1 (a); CREATE INDEX I2 ON t1 (b); EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1) +1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using index condition SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); a b CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10)); @@ -4401,15 +4420,15 @@ CREATE INDEX I1 ON t2 (a); CREATE INDEX I2 ON t2 (b); EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t2 ref I1 I1 4 test.t2.b 2 Using where; Using index; FirstMatch(t2) +1 PRIMARY t2 index I1 I1 4 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t2 ref I2 I2 13 test.t2.a 1 Using index condition SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); a b EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1) +1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using index condition SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); a b DROP TABLE t1,t2; @@ -4439,10 +4458,13 @@ out_a MIN(b) 1 2 2 4 DROP TABLE t1; +# +# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +# CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); -INSERT INTO t1 VALUES (1),(2); -INSERT INTO t2 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1),(2),(1000); SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); 2 2 @@ -4450,8 +4472,8 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`a` @@ -4459,9 +4481,9 @@ EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 3 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 @@ -5697,7 +5719,8 @@ DROP TABLE IF EXISTS ot1, ot4, it2, it3; CREATE TABLE t1 (a int) ; INSERT INTO t1 VALUES (NULL), (1), (NULL), (2); CREATE TABLE t2 (a int, INDEX idx(a)) ; -INSERT INTO t2 VALUES (NULL), (1), (NULL); +INSERT INTO t2 VALUES (NULL), (1), (NULL),(1000); +insert into t2 select seq from seq_3_to_500; SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a); a @@ -5707,7 +5730,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 502 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); a @@ -5717,7 +5740,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY t2 ref idx idx 5 test.t1.a 2 Using index; FirstMatch(t1) +1 PRIMARY t2 ref idx idx 5 test.t1.a 11 Using index; FirstMatch(t1) DROP TABLE t1,t2; # # BUG#752992: Wrong results for a subquery with 'semijoin=on' @@ -5734,9 +5757,9 @@ SET @save_join_cache_level=@@join_cache_level; SET join_cache_level=0; EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3 -1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index -1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(it) +1 PRIMARY it index PRIMARY PRIMARY 4 NULL 3 Using index +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.it.pk 1 +1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(t1) SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); pk i 11 0 @@ -6633,7 +6656,7 @@ SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquer EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 1 Using index SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); a 2009-01-01 @@ -6836,7 +6859,7 @@ FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 WHERE alias1.a = alias2.a OR ('Moscow') IN ( SELECT a FROM t1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY alias1 index a a 19 NULL 11 Using where; Using index -1 PRIMARY alias2 ref a a 19 test.alias1.a 2 Using index +1 PRIMARY alias2 ref a a 19 test.alias1.a 1 Using index 1 PRIMARY alias3 index NULL a 19 NULL 11 Using index; Using join buffer (flat, BNL join) 2 SUBQUERY t1 index_subquery a a 19 const 1 Using index; Using where SELECT MAX( alias2.a ) @@ -6986,7 +7009,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index +1 PRIMARY t3 ref d d 5 test.t2.b 1 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; @@ -7018,7 +7041,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields @@ -7051,7 +7074,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-5991: crash in Item_field::used_tables diff --git a/mysql-test/main/subselect_no_opts.result b/mysql-test/main/subselect_no_opts.result index 15688fc1717..f9561178ca5 100644 --- a/mysql-test/main/subselect_no_opts.result +++ b/mysql-test/main/subselect_no_opts.result @@ -898,6 +898,9 @@ select (select a+1) from t1; NULL 4.5 drop table t1; +# +# Null with keys +# CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a)); CREATE TABLE t2 (a int(11) default '0', INDEX (a)); INSERT INTO t1 VALUES (1),(2),(3),(4); @@ -1429,6 +1432,9 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); a 1 +# +# IN subselect optimization test +# create table t1 (a int not null, b int, primary key (a)); create table t2 (a int not null, primary key (a)); create table t3 (a int not null, b int, primary key (a)); @@ -1475,23 +1481,19 @@ insert into t1 values (1,10), (2,20), (3,30), (4,40); create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 -select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D; +select rand()*100000+200,rand(1)*100000 from t0 A, t0 B, t0 C, t0 D; insert into t2 values (2), (3), (4), (5); insert into t3 values (10,3), (20,4), (30,5); -select * from t2 where t2.a in (select a from t1); -a -2 -3 -4 explain extended select * from t2 where t2.a in (select a from t1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index 2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a))) -select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +select * from t2 where t2.a in (select a from t1); a 2 +3 4 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra @@ -1499,18 +1501,28 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where `test`.`t1`.`b` <> 30 and (`test`.`t2`.`a`) = `test`.`t1`.`a`))) +select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +a +2 +4 +explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 100.00 Using index +2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 33.33 Using where; Using index; Using join buffer (flat, BNL join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`b` and (`test`.`t2`.`a`) = `test`.`t1`.`a`)) select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 3 -explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +insert into t1 values (3,31); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t1 ref a a 10 func,test.t3.a 1167 100.00 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`a` and (`test`.`t2`.`a`) = `test`.`t1`.`a`)) -insert into t1 values (3,31); +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where `test`.`t1`.`b` <> 30 and (`test`.`t2`.`a`) = `test`.`t1`.`a`))) select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 @@ -1520,12 +1532,6 @@ select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31 a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where -Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where `test`.`t1`.`b` <> 30 and (`test`.`t2`.`a`) = `test`.`t1`.`a`))) drop table t0, t1, t2, t3; create table t1 (a int, b int); create table t2 (a int, b int); @@ -1587,6 +1593,9 @@ Note 1003 (select 'tttt' AS `s1` from dual) s1 tttt drop table t1; +# +# IN optimisation test results +# create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); @@ -2420,19 +2429,22 @@ a 1 3 DROP TABLE t1; +# +# SELECT(EXISTS * ...)optimisation +# create table t1 (a int, b int); -insert into t1 values (1,2),(3,4); -select * from t1 up where exists (select * from t1 where t1.a=up.a); -a b -1 2 -3 4 -explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a); +insert into t1 values (1,2),(3,4),(5,6),(7,8); +insert into t1 select seq,seq from seq_20_to_40; +select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); +sum(a+b) +1296 +explain extended select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY up ALL NULL NULL NULL NULL 25 100.00 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 25 100.00 Using where Warnings: Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where (`test`.`up`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where (`test`.`up`.`a`) = `test`.`t1`.`a`)) +Note 1003 /* select#1 */ select sum(`test`.`up`.`a` + `test`.`up`.`b`) AS `sum(a+b)` from `test`.`t1` `up` where (`test`.`up`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where (`test`.`up`.`a`) = `test`.`t1`.`a`)) drop table t1; CREATE TABLE t1 (t1_a int); INSERT INTO t1 VALUES (1); @@ -3099,9 +3111,13 @@ retailerID statusID changed 0048 1 2006-01-06 12:37:50 0059 1 2006-01-06 12:37:50 drop table t1; +# +# Bug#21180 Subselect with index for both WHERE and ORDER BY +# produces empty result +# create table t1(a int, primary key (a)); insert into t1 values (10); -create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +create table t2 (a int primary key, b varchar(32), c int, unique key cb(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); analyze table t1; @@ -3114,7 +3130,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using where +2 SUBQUERY t2 range cb cb 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3126,7 +3142,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using index condition +2 SUBQUERY t2 range cb cb 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -4224,8 +4240,8 @@ INSERT INTO t2 VALUES (7), (5), (1), (3); SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); id st -3 FL 1 GA +3 FL 7 FL SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) @@ -4326,6 +4342,9 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; 0 0 DROP TABLE t1, t2; +# +# Bug#28076 inconsistent binary/varbinary comparison +# CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)); INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43); SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1); @@ -4388,7 +4407,7 @@ CREATE INDEX I2 ON t1 (b); EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 1 Using index; Using where SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); a b CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10)); @@ -4398,14 +4417,14 @@ CREATE INDEX I2 ON t2 (b); EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 1 Using index; Using where SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); a b EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 1 Using index; Using where SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); a b DROP TABLE t1,t2; @@ -4435,10 +4454,13 @@ out_a MIN(b) 1 2 2 4 DROP TABLE t1; +# +# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +# CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); -INSERT INTO t1 VALUES (1),(2); -INSERT INTO t2 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1),(2),(1000); SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); 2 2 @@ -4446,8 +4468,8 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select 2 AS `2` from `test`.`t1` where (`test`.`t1`.`a`,(/* select#2 */ select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t1`.`a`) = `test`.`t2`.`a`)) @@ -4455,9 +4477,9 @@ EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 3 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 @@ -5693,7 +5715,8 @@ DROP TABLE IF EXISTS ot1, ot4, it2, it3; CREATE TABLE t1 (a int) ; INSERT INTO t1 VALUES (NULL), (1), (NULL), (2); CREATE TABLE t2 (a int, INDEX idx(a)) ; -INSERT INTO t2 VALUES (NULL), (1), (NULL); +INSERT INTO t2 VALUES (NULL), (1), (NULL),(1000); +insert into t2 select seq from seq_3_to_500; SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a); a @@ -5703,7 +5726,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 502 Using where SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); a @@ -5713,7 +5736,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 DEPENDENT SUBQUERY t2 index_subquery idx idx 5 func 2 Using index +2 DEPENDENT SUBQUERY t2 index_subquery idx idx 5 func 58 Using index DROP TABLE t1,t2; # # BUG#752992: Wrong results for a subquery with 'semijoin=on' @@ -6073,7 +6096,7 @@ WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where +2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 1 Using index; Using where SELECT col_int_nokey FROM ot WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); @@ -6629,7 +6652,7 @@ SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquer EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 1 Using index SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); a 2009-01-01 @@ -6832,7 +6855,7 @@ FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 WHERE alias1.a = alias2.a OR ('Moscow') IN ( SELECT a FROM t1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY alias1 index a a 19 NULL 11 Using where; Using index -1 PRIMARY alias2 ref a a 19 test.alias1.a 2 Using index +1 PRIMARY alias2 ref a a 19 test.alias1.a 1 Using index 1 PRIMARY alias3 index NULL a 19 NULL 11 Using index; Using join buffer (flat, BNL join) 2 SUBQUERY t1 index_subquery a a 19 const 1 Using index; Using where SELECT MAX( alias2.a ) @@ -6983,7 +7006,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index +1 PRIMARY t3 ref d d 5 test.t2.b 1 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; @@ -7015,7 +7038,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields @@ -7049,7 +7072,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-5991: crash in Item_field::used_tables diff --git a/mysql-test/main/subselect_no_scache.result b/mysql-test/main/subselect_no_scache.result index e3bdddbf84b..8083057eddf 100644 --- a/mysql-test/main/subselect_no_scache.result +++ b/mysql-test/main/subselect_no_scache.result @@ -351,7 +351,7 @@ patient_uq clinic_uq explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index -1 PRIMARY t6 ALL i1 NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t6 ref i1 i1 5 test.t7.uq 1 100.00 Warnings: Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t7` join `test`.`t6` where `test`.`t6`.`clinic_uq` = `test`.`t7`.`uq` @@ -901,6 +901,9 @@ select (select a+1) from t1; NULL 4.5 drop table t1; +# +# Null with keys +# CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a)); CREATE TABLE t2 (a int(11) default '0', INDEX (a)); INSERT INTO t1 VALUES (1),(2),(3),(4); @@ -1432,6 +1435,9 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); a 1 +# +# IN subselect optimization test +# create table t1 (a int not null, b int, primary key (a)); create table t2 (a int not null, primary key (a)); create table t3 (a int not null, b int, primary key (a)); @@ -1455,21 +1461,21 @@ a 4 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using where +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 3 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 -1 PRIMARY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where `test`.`t3`.`a` = `test`.`t1`.`b` and `test`.`t1`.`a` = `test`.`t2`.`a` +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where `test`.`t3`.`a` = `test`.`t1`.`b` and `test`.`t2`.`a` = `test`.`t1`.`a` drop table t1, t2, t3; create table t1 (a int, b int, index a (a,b)); create table t2 (a int, index a (a)); @@ -1478,42 +1484,48 @@ insert into t1 values (1,10), (2,20), (3,30), (4,40); create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 -select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D; +select rand()*100000+200,rand(1)*100000 from t0 A, t0 B, t0 C, t0 D; insert into t2 values (2), (3), (4), (5); insert into t3 values (10,3), (20,4), (30,5); +explain extended select * from t2 where t2.a in (select a from t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using index; FirstMatch(t2) +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` select * from t2 where t2.a in (select a from t1); a 2 3 4 -explain extended select * from t2 where t2.a in (select a from t1); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2) +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using where; Using index; FirstMatch(t2) Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2) -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 -select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); -a -2 -3 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index 1 PRIMARY t3 range a a 5 NULL 3 100.00 Using where; Using index -1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2) +1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 0.29 Using index; FirstMatch(t2) Warnings: Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where `test`.`t1`.`b` = `test`.`t3`.`a` and `test`.`t1`.`a` = `test`.`t2`.`a` +select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +a +2 +3 insert into t1 values (3,31); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index +1 PRIMARY t1 ref a a 5 test.t2.a 101 0.99 Using where; Using index; FirstMatch(t2) +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 @@ -1523,12 +1535,6 @@ select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31 a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index -1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2) -Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`a` = `test`.`t2`.`a` and `test`.`t1`.`b` <> 30 drop table t0, t1, t2, t3; create table t1 (a int, b int); create table t2 (a int, b int); @@ -1590,6 +1596,9 @@ Note 1003 (select 'tttt' AS `s1` from dual) s1 tttt drop table t1; +# +# IN optimisation test results +# create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); @@ -2423,20 +2432,23 @@ a 1 3 DROP TABLE t1; +# +# SELECT(EXISTS * ...)optimisation +# create table t1 (a int, b int); -insert into t1 values (1,2),(3,4); -select * from t1 up where exists (select * from t1 where t1.a=up.a); -a b -1 2 -3 4 -explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a); +insert into t1 values (1,2),(3,4),(5,6),(7,8); +insert into t1 select seq,seq from seq_20_to_40; +select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); +sum(a+b) +1296 +explain extended select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY up ALL NULL NULL NULL NULL 25 100.00 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 25 100.00 Warnings: Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` semi join (`test`.`t1`) where 1 +Note 1003 select sum(`test`.`up`.`a` + `test`.`up`.`b`) AS `sum(a+b)` from `test`.`t1` `up` semi join (`test`.`t1`) where 1 drop table t1; CREATE TABLE t1 (t1_a int); INSERT INTO t1 VALUES (1); @@ -3104,9 +3116,13 @@ retailerID statusID changed 0048 1 2006-01-06 12:37:50 0059 1 2006-01-06 12:37:50 drop table t1; +# +# Bug#21180 Subselect with index for both WHERE and ORDER BY +# produces empty result +# create table t1(a int, primary key (a)); insert into t1 values (10); -create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +create table t2 (a int primary key, b varchar(32), c int, unique key cb(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); analyze table t1; @@ -3119,7 +3135,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using where +2 SUBQUERY t2 range cb cb 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3131,7 +3147,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using index condition +2 SUBQUERY t2 range cb cb 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -4231,8 +4247,8 @@ INSERT INTO t2 VALUES (7), (5), (1), (3); SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); id st -3 FL 1 GA +3 FL 7 FL SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) @@ -4333,6 +4349,9 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; 0 0 DROP TABLE t1, t2; +# +# Bug#28076 inconsistent binary/varbinary comparison +# CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)); INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43); SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1); @@ -4394,8 +4413,8 @@ CREATE INDEX I1 ON t1 (a); CREATE INDEX I2 ON t1 (b); EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1) +1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using index condition SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); a b CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10)); @@ -4404,15 +4423,15 @@ CREATE INDEX I1 ON t2 (a); CREATE INDEX I2 ON t2 (b); EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t2 ref I1 I1 4 test.t2.b 2 Using where; Using index; FirstMatch(t2) +1 PRIMARY t2 index I1 I1 4 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t2 ref I2 I2 13 test.t2.a 1 Using index condition SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); a b EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where -1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1) +1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan +1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using index condition SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); a b DROP TABLE t1,t2; @@ -4442,10 +4461,13 @@ out_a MIN(b) 1 2 2 4 DROP TABLE t1; +# +# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +# CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); -INSERT INTO t1 VALUES (1),(2); -INSERT INTO t2 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1),(2),(1000); SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); 2 2 @@ -4453,19 +4475,18 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where 1 +Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`a` EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 3 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 @@ -5704,7 +5725,8 @@ DROP TABLE IF EXISTS ot1, ot4, it2, it3; CREATE TABLE t1 (a int) ; INSERT INTO t1 VALUES (NULL), (1), (NULL), (2); CREATE TABLE t2 (a int, INDEX idx(a)) ; -INSERT INTO t2 VALUES (NULL), (1), (NULL); +INSERT INTO t2 VALUES (NULL), (1), (NULL),(1000); +insert into t2 select seq from seq_3_to_500; SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a); a @@ -5715,7 +5737,7 @@ WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 502 SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); a @@ -5724,9 +5746,8 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 index idx idx 5 NULL 3 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY t2 ref idx idx 5 test.t1.a 11 Using index; FirstMatch(t1) DROP TABLE t1,t2; # # BUG#752992: Wrong results for a subquery with 'semijoin=on' @@ -5743,9 +5764,9 @@ SET @save_join_cache_level=@@join_cache_level; SET join_cache_level=0; EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3 -1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index -1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(it) +1 PRIMARY it index PRIMARY PRIMARY 4 NULL 3 Using index +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.it.pk 1 +1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(t1) SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); pk i 11 0 @@ -6086,8 +6107,7 @@ WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index +1 PRIMARY it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index; FirstMatch(ot) SELECT col_int_nokey FROM ot WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); @@ -6099,8 +6119,7 @@ WHERE (col_varchar_nokey, 'x') IN (SELECT col_varchar_key, col_varchar_key2 FROM it2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index +1 PRIMARY it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index; FirstMatch(ot) SELECT col_int_nokey FROM ot WHERE (col_varchar_nokey, 'x') IN (SELECT col_varchar_key, col_varchar_key2 FROM it2); @@ -6644,7 +6663,7 @@ SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquer EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 1 Using index SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); a 2009-01-01 @@ -6847,7 +6866,7 @@ FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 WHERE alias1.a = alias2.a OR ('Moscow') IN ( SELECT a FROM t1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY alias1 index a a 19 NULL 11 Using where; Using index -1 PRIMARY alias2 ref a a 19 test.alias1.a 2 Using index +1 PRIMARY alias2 ref a a 19 test.alias1.a 1 Using index 1 PRIMARY alias3 index NULL a 19 NULL 11 Using index; Using join buffer (flat, BNL join) 2 SUBQUERY t1 index_subquery a a 19 const 1 Using index; Using where SELECT MAX( alias2.a ) @@ -6998,7 +7017,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index +1 PRIMARY t3 ref d d 5 test.t2.b 1 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; @@ -7030,7 +7049,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields @@ -7064,7 +7083,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-5991: crash in Item_field::used_tables diff --git a/mysql-test/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result index 88f8f78019e..19dae33c5c1 100644 --- a/mysql-test/main/subselect_no_semijoin.result +++ b/mysql-test/main/subselect_no_semijoin.result @@ -348,10 +348,10 @@ patient_uq clinic_uq explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where -2 MATERIALIZED t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index +2 DEPENDENT SUBQUERY t7 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index Warnings: Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <`test`.`t6`.`clinic_uq`>((`test`.`t6`.`clinic_uq`,`test`.`t6`.`clinic_uq` in ( (/* select#2 */ select `test`.`t7`.`uq` from `test`.`t7` where 1 ), (`test`.`t6`.`clinic_uq` in on distinct_key where `test`.`t6`.`clinic_uq` = ``.`uq`)))) +Note 1003 /* select#1 */ select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <`test`.`t6`.`clinic_uq`>((`test`.`t6`.`clinic_uq`,(((`test`.`t6`.`clinic_uq`) in t7 on PRIMARY)))) select * from t1 where a= (select a from t2,t4 where t2.b=t4.b); ERROR 23000: Column 'a' in field list is ambiguous drop table t1,t2,t3; @@ -898,6 +898,9 @@ select (select a+1) from t1; NULL 4.5 drop table t1; +# +# Null with keys +# CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a)); CREATE TABLE t2 (a int(11) default '0', INDEX (a)); INSERT INTO t1 VALUES (1),(2),(3),(4); @@ -911,9 +914,9 @@ a t1.a in (select t2.a from t2) explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index -2 MATERIALIZED t2 index a a 5 NULL 3 100.00 Using index +2 SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`a` from `test`.`t2` ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`a`)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<`test`.`t1`.`a`>((`test`.`t1`.`a`,(((`test`.`t1`.`a`) in t2 on a checking NULL having `test`.`t2`.`a` is null)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1` CREATE TABLE t3 (a int(11) default '0'); INSERT INTO t3 VALUES (1),(2),(3); SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1; @@ -925,10 +928,10 @@ a t1.a in (select t2.a from t2,t3 where t3.a=t2.a) explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index -2 MATERIALIZED t2 index a a 5 NULL 3 100.00 Using index -2 MATERIALIZED t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 3 100.00 Using where +2 MATERIALIZED t2 ref a a 5 test.t3.a 1 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t2`.`a` ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1` +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t3`.`a` ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1` drop table t1,t2,t3; # check correct NULL Processing for normal IN/ALL/ANY # and 2 ways of max/min optimization @@ -1429,6 +1432,9 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); a 1 +# +# IN subselect optimization test +# create table t1 (a int not null, b int, primary key (a)); create table t2 (a int not null, primary key (a)); create table t3 (a int not null, b int, primary key (a)); @@ -1443,9 +1449,9 @@ a explain extended select * from t2 where t2.a in (select a from t1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index -2 MATERIALIZED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` ), (`test`.`t2`.`a` in on distinct_key where `test`.`t2`.`a` = ``.`a`)))) +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY)))) select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 @@ -1453,9 +1459,9 @@ a explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index -2 MATERIALIZED t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`b` <> 30 ), (`test`.`t2`.`a` in on distinct_key where `test`.`t2`.`a` = ``.`a`)))) +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY where `test`.`t1`.`b` <> 30 and (`test`.`t2`.`a`) = `test`.`t1`.`a`)))) select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 @@ -1463,10 +1469,10 @@ a explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index -2 MATERIALIZED t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index -2 MATERIALIZED t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where +2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`a` ), (`test`.`t2`.`a` in on distinct_key where `test`.`t2`.`a` = ``.`a`)))) +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`b` and (`test`.`t2`.`a`) = `test`.`t1`.`a`))) drop table t1, t2, t3; create table t1 (a int, b int, index a (a,b)); create table t2 (a int, index a (a)); @@ -1475,23 +1481,19 @@ insert into t1 values (1,10), (2,20), (3,30), (4,40); create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); insert into t1 -select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D; +select rand()*100000+200,rand(1)*100000 from t0 A, t0 B, t0 C, t0 D; insert into t2 values (2), (3), (4), (5); insert into t3 values (10,3), (20,4), (30,5); -select * from t2 where t2.a in (select a from t1); -a -2 -3 -4 explain extended select * from t2 where t2.a in (select a from t1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index 2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a)))) -select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +select * from t2 where t2.a in (select a from t1); a 2 +3 4 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra @@ -1499,18 +1501,28 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where `test`.`t1`.`b` <> 30 and (`test`.`t2`.`a`) = `test`.`t1`.`a`)))) +select * from t2 where t2.a in (select a from t1 where t1.b <> 30); +a +2 +4 +explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 100.00 Using index +2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 33.33 Using where; Using index; Using join buffer (flat, BNL join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`b` and (`test`.`t2`.`a`) = `test`.`t1`.`a`))) select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 3 -explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); +insert into t1 values (3,31); +explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t1 ref a a 10 func,test.t3.a 1167 100.00 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`a` and (`test`.`t2`.`a`) = `test`.`t1`.`a`))) -insert into t1 values (3,31); +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where `test`.`t1`.`b` <> 30 and (`test`.`t2`.`a`) = `test`.`t1`.`a`)))) select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 @@ -1520,12 +1532,6 @@ select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31 a 2 4 -explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where -Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <`test`.`t2`.`a`>((`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where `test`.`t1`.`b` <> 30 and (`test`.`t2`.`a`) = `test`.`t1`.`a`)))) drop table t0, t1, t2, t3; create table t1 (a int, b int); create table t2 (a int, b int); @@ -1587,6 +1593,9 @@ Note 1003 (select 'tttt' AS `s1` from dual) s1 tttt drop table t1; +# +# IN optimisation test results +# create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); @@ -1614,27 +1623,27 @@ a3 1 explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index -2 MATERIALIZED t2 index s1 s1 6 NULL 2 100.00 Using index +2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<`test`.`t1`.`s1`>((`test`.`t1`.`s1`,`test`.`t1`.`s1` in ( (/* select#2 */ select `test`.`t2`.`s1` from `test`.`t2` ), (`test`.`t1`.`s1` in on distinct_key where `test`.`t1`.`s1` = ``.`s1`)))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1` +Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<`test`.`t1`.`s1`>((`test`.`t1`.`s1`,(((`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1` explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index -2 MATERIALIZED t2 index s1 s1 6 NULL 2 100.00 Using index +2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,<`test`.`t1`.`s1`>((`test`.`t1`.`s1`,`test`.`t1`.`s1` in ( (/* select#2 */ select `test`.`t2`.`s1` from `test`.`t2` ), (`test`.`t1`.`s1` in on distinct_key where `test`.`t1`.`s1` = ``.`s1`)))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1` +Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,<`test`.`t1`.`s1`>((`test`.`t1`.`s1`,(((`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1` explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index -2 MATERIALIZED t2 index s1 s1 6 NULL 2 100.00 Using index +2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<`test`.`t1`.`s1`>((`test`.`t1`.`s1`,`test`.`t1`.`s1` in ( (/* select#2 */ select `test`.`t2`.`s1` from `test`.`t2` ), (`test`.`t1`.`s1` in on distinct_key where `test`.`t1`.`s1` = ``.`s1`)))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1` +Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<`test`.`t1`.`s1`>((`test`.`t1`.`s1`,(((`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1` explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index -2 MATERIALIZED t2 range s1 s1 6 NULL 1 100.00 Using where; Using index +2 SUBQUERY t2 index_subquery s1 s1 6 func 2 50.00 Using index; Using where; Full scan on NULL key Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<`test`.`t1`.`s1`>((`test`.`t1`.`s1`,`test`.`t1`.`s1` in ( (/* select#2 */ select `test`.`t2`.`s1` from `test`.`t2` where `test`.`t2`.`s1` < 'a2' ), (`test`.`t1`.`s1` in on distinct_key where `test`.`t1`.`s1` = ``.`s1`)))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1` +Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<`test`.`t1`.`s1`>((`test`.`t1`.`s1`,(((`test`.`t1`.`s1`) in t2 on s1 checking NULL where `test`.`t2`.`s1` < 'a2' having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1` drop table t1,t2; create table t2 (a int, b int not null); create table t3 (a int); @@ -1887,9 +1896,9 @@ id text explain extended select * from t1 where id not in (select id from t1 where id < 8); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where -2 MATERIALIZED t1 range PRIMARY PRIMARY 4 NULL 7 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where !<`test`.`t1`.`id`>((`test`.`t1`.`id`,`test`.`t1`.`id` in ( (/* select#2 */ select `test`.`t1`.`id` from `test`.`t1` where `test`.`t1`.`id` < 8 ), (`test`.`t1`.`id` in on distinct_key where `test`.`t1`.`id` = ``.`id`)))) +Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where !<`test`.`t1`.`id`>((`test`.`t1`.`id`,(((`test`.`t1`.`id`) in t1 on PRIMARY where `test`.`t1`.`id` < 8 and (`test`.`t1`.`id`) = `test`.`t1`.`id`)))) explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY tt ALL NULL NULL NULL NULL 12 100.00 Using where @@ -2420,19 +2429,22 @@ a 1 3 DROP TABLE t1; +# +# SELECT(EXISTS * ...)optimisation +# create table t1 (a int, b int); -insert into t1 values (1,2),(3,4); -select * from t1 up where exists (select * from t1 where t1.a=up.a); -a b -1 2 -3 4 -explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a); +insert into t1 values (1,2),(3,4),(5,6),(7,8); +insert into t1 select seq,seq from seq_20_to_40; +select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); +sum(a+b) +1296 +explain extended select sum(a+b) from t1 up where exists (select * from t1 where t1.a=up.a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY up ALL NULL NULL NULL NULL 25 100.00 Using where +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 25 100.00 Warnings: Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <`test`.`up`.`a`>((`test`.`up`.`a`,`test`.`up`.`a` in ( (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where 1 ), (`test`.`up`.`a` in on distinct_key where `test`.`up`.`a` = ``.`a`)))) +Note 1003 /* select#1 */ select sum(`test`.`up`.`a` + `test`.`up`.`b`) AS `sum(a+b)` from `test`.`t1` `up` where <`test`.`up`.`a`>((`test`.`up`.`a`,`test`.`up`.`a` in ( (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where 1 ), (`test`.`up`.`a` in on distinct_key where `test`.`up`.`a` = ``.`a`)))) drop table t1; CREATE TABLE t1 (t1_a int); INSERT INTO t1 VALUES (1); @@ -3099,9 +3111,13 @@ retailerID statusID changed 0048 1 2006-01-06 12:37:50 0059 1 2006-01-06 12:37:50 drop table t1; +# +# Bug#21180 Subselect with index for both WHERE and ORDER BY +# produces empty result +# create table t1(a int, primary key (a)); insert into t1 values (10); -create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +create table t2 (a int primary key, b varchar(32), c int, unique key cb(c, b)); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); insert into t2(a, c, b) values (4,10,'360'), (5,10,'35998'), (6,10,'35999'); analyze table t1; @@ -3114,7 +3130,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using where +2 SUBQUERY t2 range cb cb 40 NULL 3 Using where SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; @@ -3126,7 +3142,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1 -2 SUBQUERY t2 range b b 40 NULL 3 Using index condition +2 SUBQUERY t2 range cb cb 40 NULL 3 Using index condition SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; @@ -3177,7 +3193,7 @@ INSERT INTO t2 VALUES (1),(2),(3); EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 -2 MATERIALIZED t1 index a a 5 NULL 5 Using index +2 SUBQUERY t1 index_subquery a a 5 func 3 Using index; Full scan on NULL key SELECT a, a IN (SELECT a FROM t1) FROM t2; a a IN (SELECT a FROM t1) 1 1 @@ -4224,8 +4240,8 @@ INSERT INTO t2 VALUES (7), (5), (1), (3); SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); id st -3 FL 1 GA +3 FL 7 FL SELECT id, st FROM t1 WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) @@ -4326,6 +4342,9 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; 0 0 DROP TABLE t1, t2; +# +# Bug#28076 inconsistent binary/varbinary comparison +# CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)); INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43); SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1); @@ -4388,7 +4407,7 @@ CREATE INDEX I2 ON t1 (b); EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 1 Using index; Using where SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); a b CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10)); @@ -4398,14 +4417,14 @@ CREATE INDEX I2 ON t2 (b); EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 1 Using index; Using where SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); a b EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 1 Using index; Using where SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); a b DROP TABLE t1,t2; @@ -4435,10 +4454,13 @@ out_a MIN(b) 1 2 2 4 DROP TABLE t1; +# +# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +# CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); -INSERT INTO t1 VALUES (1),(2); -INSERT INTO t2 VALUES (1),(2); +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t2 VALUES (1),(2),(1000); SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); 2 2 @@ -4446,8 +4468,8 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select 2 AS `2` from `test`.`t1` where <`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`a` from `test`.`t2` where 1 ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`a`)))) @@ -4455,9 +4477,9 @@ EXPLAIN EXTENDED SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION (SELECT 1 FROM t2 WHERE t1.a = t2.a)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 3 100.00 Using where NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 @@ -4615,7 +4637,7 @@ WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) ORDER BY outr.pk; id select_type table type possible_keys key key_len ref rows Extra x x outr ALL x x x x x x -x x t1 index x x x x x x +x x t1 eq_ref x x x x x x x x t2 index x x x x x x # should not crash on debug binaries SELECT * FROM t2 outr @@ -5693,7 +5715,8 @@ DROP TABLE IF EXISTS ot1, ot4, it2, it3; CREATE TABLE t1 (a int) ; INSERT INTO t1 VALUES (NULL), (1), (NULL), (2); CREATE TABLE t2 (a int, INDEX idx(a)) ; -INSERT INTO t2 VALUES (NULL), (1), (NULL); +INSERT INTO t2 VALUES (NULL), (1), (NULL),(1000); +insert into t2 select seq from seq_3_to_500; SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a); a @@ -5703,7 +5726,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 502 SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); a @@ -5713,7 +5736,7 @@ SELECT * FROM t1 WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 MATERIALIZED t2 index idx idx 5 NULL 3 Using index +2 DEPENDENT SUBQUERY t2 index_subquery idx idx 5 func 58 Using index DROP TABLE t1,t2; # # BUG#752992: Wrong results for a subquery with 'semijoin=on' @@ -5731,8 +5754,8 @@ SET join_cache_level=0; EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 MATERIALIZED t2 index NULL PRIMARY 4 NULL 3 Using index -2 MATERIALIZED it index PRIMARY PRIMARY 4 NULL 3 Using index +2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index +2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); pk i 11 0 @@ -6073,7 +6096,7 @@ WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where +2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 1 Using index; Using where SELECT col_int_nokey FROM ot WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); @@ -6629,7 +6652,7 @@ SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquer EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 1 Using index SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); a 2009-01-01 @@ -6832,7 +6855,7 @@ FROM t1 AS alias1, t1 AS alias2, t1 AS alias3 WHERE alias1.a = alias2.a OR ('Moscow') IN ( SELECT a FROM t1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY alias1 index a a 19 NULL 11 Using where; Using index -1 PRIMARY alias2 ref a a 19 test.alias1.a 2 Using index +1 PRIMARY alias2 ref a a 19 test.alias1.a 1 Using index 1 PRIMARY alias3 index NULL a 19 NULL 11 Using index; Using join buffer (flat, BNL join) 2 SUBQUERY t1 index_subquery a a 19 const 1 Using index; Using where SELECT MAX( alias2.a ) @@ -6983,7 +7006,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where -1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index +1 PRIMARY t3 ref d d 5 test.t2.b 1 Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @tmp_mdev410=@@global.userstat; set global userstat=on; @@ -7015,7 +7038,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields @@ -7049,7 +7072,7 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY t1 range a a 5 NULL 2 Using where; Using index -2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index +2 SUBQUERY t2 ref b b 5 test.t1.a 1 Using index DROP TABLE t1,t2; # # MDEV-5991: crash in Item_field::used_tables @@ -7415,12 +7438,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -7444,12 +7470,15 @@ EXPLAIN { "query_block": { "select_id": 3, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "1 = t3.c" } diff --git a/mysql-test/main/subselect_no_semijoin.test b/mysql-test/main/subselect_no_semijoin.test index 84d312c03c8..83488829448 100644 --- a/mysql-test/main/subselect_no_semijoin.test +++ b/mysql-test/main/subselect_no_semijoin.test @@ -24,6 +24,7 @@ INSERT INTO t3 VALUES (4),(5); SET @tmp19714=@@optimizer_switch; SET optimizer_switch='subquery_cache=off'; +--source include/explain-no-costs.inc explain format=json SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; diff --git a/mysql-test/main/subselect_partial_match.result b/mysql-test/main/subselect_partial_match.result index 52c30492675..16a487445e4 100644 --- a/mysql-test/main/subselect_partial_match.result +++ b/mysql-test/main/subselect_partial_match.result @@ -760,20 +760,19 @@ drop table t1,t2; # LP BUG#601156 # CREATE TABLE t1 (a1 int DEFAULT NULL, a2 int DEFAULT NULL); -INSERT INTO t1 VALUES (NULL,2); -INSERT INTO t1 VALUES (4,NULL); +INSERT INTO t1 VALUES (NULL,2), (4,NULL),(100,100); CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL); -INSERT INTO t2 VALUES (6,NULL); -INSERT INTO t2 VALUES (NULL,0); +INSERT INTO t2 VALUES (6,NULL), (NULL,0),(1000,1000); +insert into t2 select seq,seq from seq_2000_to_2100; set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on'; set @tmp_optimizer_switch=@@optimizer_switch; set optimizer_switch='derived_merge=off,derived_with_keys=off'; EXPLAIN EXTENDED SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 100.00 -2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using where -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY ALL NULL NULL NULL NULL 3 100.00 +2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using where +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 104 100.00 Warnings: Note 1003 /* select#1 */ select `table1`.`a1` AS `a1`,`table1`.`a2` AS `a2` from (/* select#2 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where !((`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( (/* select#3 */ select `test`.`t2`.`b2` from `test`.`t2` ), (`test`.`t1`.`a1` in on distinct_key where `test`.`t1`.`a1` = ``.`b2`))))) `table1` set optimizer_switch=@tmp_optimizer_switch; @@ -782,12 +781,13 @@ DROP TABLE t1, t2; # LP BUG#613009 Crash in Ordered_key::get_field_idx # set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off'; -create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL); -insert into t1 values (NULL, 'a21'), (NULL, 'a22'); +create table t1 (a1 char(4) DEFAULT NULL, a2 char(4) DEFAULT NULL); +insert into t1 values (NULL, 'a21'), (NULL, 'a22'), ('xxx','xxx'); +insert into t1 select seq,seq from seq_2000_to_2100; explain select * from t1 where (a1, a2) not in (select a1, a2 from t1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 104 Using where +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 104 select * from t1 where (a1, a2) not in (select a1, a2 from t1); a1 a2 drop table t1; diff --git a/mysql-test/main/subselect_partial_match.test b/mysql-test/main/subselect_partial_match.test index fd1e6de716c..9a32ef5491c 100644 --- a/mysql-test/main/subselect_partial_match.test +++ b/mysql-test/main/subselect_partial_match.test @@ -2,6 +2,7 @@ # Tests for # MWL#68: Subquery optimization: Efficient NOT IN execution with NULLs # +--source include/have_sequence.inc set @save_optimizer_switch=@@optimizer_switch; @@ -614,11 +615,11 @@ drop table t1,t2; --echo # CREATE TABLE t1 (a1 int DEFAULT NULL, a2 int DEFAULT NULL); -INSERT INTO t1 VALUES (NULL,2); -INSERT INTO t1 VALUES (4,NULL); +INSERT INTO t1 VALUES (NULL,2), (4,NULL),(100,100); CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL); -INSERT INTO t2 VALUES (6,NULL); -INSERT INTO t2 VALUES (NULL,0); +INSERT INTO t2 VALUES (6,NULL), (NULL,0),(1000,1000); + +insert into t2 select seq,seq from seq_2000_to_2100; set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on'; @@ -636,8 +637,9 @@ DROP TABLE t1, t2; set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off'; -create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL); -insert into t1 values (NULL, 'a21'), (NULL, 'a22'); +create table t1 (a1 char(4) DEFAULT NULL, a2 char(4) DEFAULT NULL); +insert into t1 values (NULL, 'a21'), (NULL, 'a22'), ('xxx','xxx'); +insert into t1 select seq,seq from seq_2000_to_2100; explain select * from t1 where (a1, a2) not in (select a1, a2 from t1); select * from t1 where (a1, a2) not in (select a1, a2 from t1); drop table t1; diff --git a/mysql-test/main/subselect_sj.result b/mysql-test/main/subselect_sj.result index b69471edce3..a33fb8cea6e 100644 --- a/mysql-test/main/subselect_sj.result +++ b/mysql-test/main/subselect_sj.result @@ -76,24 +76,24 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where `test`.`t12`.`pk` = `test`.`t10`.`a` and `test`.`t10`.`pk` = `test`.`t1`.`a` subqueries within outer joins go into ON expr. -explAin extended +explain extended select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10)); -id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA +id select_type table type possible_keys key key_len ref rows filtered ExtrA 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 1 PRIMARY A ALL NULL NULL NULL NULL 3 100.00 Using where 1 PRIMARY B ALL NULL NULL NULL NULL 3 100.00 Using where -2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index +2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(`test`.`A`.`A` = `test`.`t1`.`A` And (`test`.`B`.`A`,`test`.`B`.`A` in ( (/* select#2 */ select `test`.`t10`.`pk` from `test`.`t10` ), (`test`.`B`.`A` in on distinct_key where `test`.`B`.`A` = ``.`pk`)))) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(`test`.`A`.`A` = `test`.`t1`.`A` And (`test`.`B`.`A`,(((`test`.`B`.`A`) in t10 on PRIMARY)))) where 1 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)" -explAin extended +explain extended select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10)); -id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA +id select_type table type possible_keys key key_len ref rows filtered ExtrA 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where -2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index +2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`A` = `test`.`t1`.`A` And (`test`.`t1`.`A`,`test`.`t1`.`A` in ( (/* select#2 */ select `test`.`t10`.`pk` from `test`.`t10` ), (`test`.`t1`.`A` in on distinct_key where `test`.`t1`.`A` = ``.`pk`)))) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`A` = `test`.`t1`.`A` And (`test`.`t1`.`A`,(((`test`.`t2`.`A`) in t10 on PRIMARY)))) where 1 set @save_join_buffer_size=@@join_buffer_size; set join_buffer_size=8*1024; we shouldn't flatten if we're going to get a join of > MAX_TABLES. @@ -160,26 +160,26 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY s47 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) 1 PRIMARY s48 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) 1 PRIMARY s49 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m00 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY m01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m02 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m03 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m04 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m05 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m06 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m07 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m08 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m09 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m10 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m11 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m12 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m13 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m14 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m15 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m16 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m17 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m18 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m19 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m00 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED m01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m02 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m03 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m04 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m05 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m06 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m07 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m08 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m09 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m10 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m11 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m12 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m13 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m14 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m15 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m16 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m17 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m18 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m19 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10)) where t1.a < 5; @@ -344,8 +344,8 @@ WHERE PNUM IN (SELECT PNUM FROM PROJ)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY STAFF ALL NULL NULL NULL NULL 5 -1 PRIMARY PROJ ALL NULL NULL NULL NULL 6 -1 PRIMARY WORKS ALL NULL NULL NULL NULL 12 Using where; FirstMatch(STAFF) +1 PRIMARY PROJ ALL NULL NULL NULL NULL 6 Start temporary +1 PRIMARY WORKS ALL NULL NULL NULL NULL 12 Using where; End temporary SELECT EMPNUM, EMPNAME FROM STAFF WHERE EMPNUM IN @@ -502,7 +502,7 @@ EXPLAIN EXTENDED SELECT vkey FROM t0 WHERE pk IN id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t0 ALL PRIMARY NULL NULL NULL 5 100.00 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t0.pk 1 100.00 Using where -1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 2 100.00 Using index; FirstMatch(t1) +1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 1 100.00 Using index; FirstMatch(t1) Warnings: Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where `test`.`t1`.`pk` = `test`.`t0`.`pk` and `test`.`t2`.`vkey` = `test`.`t1`.`vnokey` SELECT vkey FROM t0 WHERE pk IN @@ -763,16 +763,16 @@ explain extended select a from t1 where a in (select c from t2 where d >= some(select e from t3 where b=e)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 -1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Using where; FirstMatch(t1) +1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 16.67 Using where; End temporary; Using join buffer (flat, BNL join) 3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where Warnings: Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`c` = `test`.`t1`.`a` and (<`test`.`t2`.`d`,`test`.`t1`.`b`>((`test`.`t2`.`d`,(/* select#3 */ select `test`.`t3`.`e` from `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`e` and (`test`.`t2`.`d`) >= `test`.`t3`.`e`)))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t2`.`c` and (<`test`.`t2`.`d`,`test`.`t1`.`b`>((`test`.`t2`.`d`,(/* select#3 */ select `test`.`t3`.`e` from `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`e` and (`test`.`t2`.`d`) >= `test`.`t3`.`e`)))) show warnings; Level Code Message Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`c` = `test`.`t1`.`a` and (<`test`.`t2`.`d`,`test`.`t1`.`b`>((`test`.`t2`.`d`,(/* select#3 */ select `test`.`t3`.`e` from `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`e` and (`test`.`t2`.`d`) >= `test`.`t3`.`e`)))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t2`.`c` and (<`test`.`t2`.`d`,`test`.`t1`.`b`>((`test`.`t2`.`d`,(/* select#3 */ select `test`.`t3`.`e` from `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`e` and (`test`.`t2`.`d`) >= `test`.`t3`.`e`)))) select a from t1 where a in (select c from t2 where d >= some(select e from t3 where b=e)); a @@ -802,13 +802,13 @@ PRIMARY KEY (pk) INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff', 'ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')); CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')); +insert into t2 (pk) values (-1),(0); EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 11 func,func 1 100.00 -2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1) Warnings: -Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`pk` > 0 +Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b` and `test`.`t2`.`pk` > 0 SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); pk 2 @@ -1249,8 +1249,8 @@ INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1); EXPLAIN SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index k k 10 NULL 4 Using where; Using index; Start temporary -1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY t2 ref k k 5 test.t1.i 1 Using where; Using index; Start temporary; End temporary SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); i 1 @@ -1612,7 +1612,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY A index PRIMARY PRIMARY 4 NULL 3 Using index 1 PRIMARY C eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index 1 PRIMARY D eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index -1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; Start temporary; End temporary +1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(D) SELECT * FROM t1 A WHERE A.t1field IN (SELECT A.t1field FROM t2 B) AND @@ -1626,7 +1626,7 @@ drop table t1,t2; # BUG#787299: Valgrind complains on a join query with two IN subqueries # create table t1 (a int); -insert into t1 values (1), (2), (3); +insert into t1 values (1), (2), (3),(1000),(2000); create table t2 as select * from t1; select * from t1 A, t1 B where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); @@ -1634,16 +1634,18 @@ a a 1 1 2 2 3 3 +1000 1000 +2000 2000 explain select * from t1 A, t1 B where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY A ALL NULL NULL NULL NULL 3 +1 PRIMARY A ALL NULL NULL NULL NULL 5 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 PRIMARY B ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED C ALL NULL NULL NULL NULL 3 -3 MATERIALIZED D ALL NULL NULL NULL NULL 3 +2 MATERIALIZED C ALL NULL NULL NULL NULL 5 +3 MATERIALIZED D ALL NULL NULL NULL NULL 5 drop table t1, t2; # # BUG#784441: Abort on semijoin with a view as the inner table @@ -1980,7 +1982,7 @@ f1 f3 f4 f2 f4 DROP TABLE t1,t2,t3; # # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90 -# (Original testcase) +# (Original, slightly modified testcase) # CREATE TABLE t1 (f1 int, f2 int ); INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL); @@ -1990,24 +1992,22 @@ CREATE TABLE t3 ( f1 int, f3 int ); INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0); CREATE TABLE t4 ( f2 int, KEY (f2) ); INSERT INTO t4 VALUES (0),(NULL); -CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ; +INSERT INTO t4 VALUES (0),(NULL),(-1),(-2),(-3); # The following must not have outer joins: explain extended -SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4 where f2 = 0 or f2 IS NULL); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t4 ref_or_null f2 f2 5 const 4 25.00 Using where; Using index; FirstMatch(t2) 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) -2 MATERIALIZED t4 index f2 f2 5 NULL 2 100.00 Using index Warnings: -Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where `test`.`t3`.`f1` = `test`.`t1`.`f1` and `test`.`t1`.`f2` = `test`.`t2`.`f2` -SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); +Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where `test`.`t4`.`f2` = `test`.`t2`.`f3` and `test`.`t3`.`f1` = `test`.`t1`.`f1` and `test`.`t1`.`f2` = `test`.`t2`.`f2` and (`test`.`t2`.`f3` = 0 or `test`.`t2`.`f3` is null) +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4 where f2 = 0 or f2 IS NULL); f1 f2 f3 f3 2 0 0 0 4 0 0 0 4 0 0 0 -drop view v4; drop table t1, t2, t3, t4; # # BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90 @@ -2153,9 +2153,9 @@ INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5); explain SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 2 Using index; Using join buffer (flat, BNL join) -1 PRIMARY t3 ALL b NULL NULL NULL 5 Using where; Start temporary; End temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY t3 ref b b 5 test.t1.b 1 Using where; Start temporary +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 Using index; End temporary SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3); b a 5 6 @@ -2178,10 +2178,10 @@ INSERT INTO t5 VALUES (7,0),(9,0); explain SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan -1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where -1 PRIMARY t4 ALL NULL NULL NULL NULL 3 FirstMatch(t5) -1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; Start temporary +1 PRIMARY t2 ref b b 5 test.t5.b 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 +1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; End temporary; Using join buffer (flat, BNL join) SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b); a 0 @@ -2260,10 +2260,10 @@ alias1.c IN (SELECT SQ3_alias1.b FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2) LIMIT 100; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 20 -1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) +1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) -1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Start temporary +1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Start temporary +1 PRIMARY ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) 1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary 2 DERIVED t2 ALL NULL NULL NULL NULL 20 create table t3 as @@ -2436,9 +2436,9 @@ SET SESSION optimizer_switch='loosescan=off'; EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary -1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +1 PRIMARY t2 range idx idx 4 NULL 2 Using where; Using index +1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index; FirstMatch(t1) SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b); a 5 @@ -2446,9 +2446,9 @@ SET SESSION optimizer_switch='loosescan=on'; EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary -1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +1 PRIMARY t2 range idx idx 4 NULL 2 Using where; Using index +1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index; FirstMatch(t1) SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b); a 5 @@ -2499,10 +2499,9 @@ SELECT * FROM t1, t2 WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 system NULL NULL NULL NULL 1 -1 PRIMARY ALL distinct_key NULL NULL NULL 1 1 PRIMARY t1 ref a a 5 const 1 Using index 1 PRIMARY t2 ref a a 5 func 1 Using index -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 0 +1 PRIMARY t4 ALL NULL NULL NULL NULL 0 FirstMatch(t2); Using join buffer (flat, BNL join) SELECT * FROM t1, t2 WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4); a a @@ -2562,7 +2561,7 @@ INSERT INTO t1 VALUES (6,3),(7,1),(8,4),(9,3),(10,2); CREATE TABLE t2 ( c INT, d INT, KEY(c) ); INSERT INTO t2 VALUES -(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); +(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1),(11,11); analyze table t1,t2; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected @@ -2572,35 +2571,35 @@ test.t2 analyze status OK explain SELECT a, b, d FROM t1, t2 WHERE ( b, d ) IN -( SELECT b, d FROM t1, t2 WHERE b = c ); +( SELECT b, d FROM t1 as t3, t2 as t4 WHERE b = c ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 7 -1 PRIMARY t1 index b b 5 NULL 10 Using where; Using index; LooseScan -1 PRIMARY t2 ref c c 5 test.t1.b 1 Using where; FirstMatch(t1) -1 PRIMARY t1 ref b b 5 test.t1.b 2 +1 PRIMARY t3 index b b 5 NULL 10 Using where; Using index; Start temporary +1 PRIMARY t4 ref c c 5 test.t3.b 1 +1 PRIMARY t1 ALL b NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (flat, BNL join) SELECT a, b, d FROM t1, t2 WHERE ( b, d ) IN -( SELECT b, d FROM t1, t2 WHERE b = c ); +( SELECT b, d FROM t1 as t3, t2 as t4 WHERE b = c ); a b d -2 1 2 -7 1 2 -8 4 2 1 2 1 -4 2 1 +1 2 1 +10 2 1 10 2 1 -3 3 3 -6 3 3 -9 3 3 2 1 2 -7 1 2 -8 4 2 +2 1 2 +3 3 3 +3 3 3 +4 2 1 +4 2 1 5 5 5 -3 3 3 6 3 3 +6 3 3 +7 1 2 +7 1 2 +8 4 2 +8 4 2 +9 3 3 9 3 3 -1 2 1 -4 2 1 -10 2 1 DROP TABLE t1, t2; # Another testcase for the above that still uses LooseScan: create table t0(a int primary key); @@ -2769,21 +2768,21 @@ WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_1 ALL NULL NULL NULL NULL 11 Using where 1 PRIMARY t1_2 ALL NULL NULL NULL NULL 11 -1 PRIMARY ref key0 key0 5 test.t1_1.a 2 Using where; FirstMatch(t1_2) +1 PRIMARY ref key0 key0 5 test.t1_1.a 1 Using where; FirstMatch(t1_2) 3 DERIVED t1 ALL NULL NULL NULL NULL 11 SELECT * FROM t1 AS t1_1, t1 AS t1_2 WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 ); a b a b -3 1 9 1 -5 8 4 0 -3 9 9 1 2 4 4 0 2 4 6 8 2 6 4 0 2 6 6 8 +3 1 9 1 +3 9 9 1 5 4 4 0 +5 4 4 0 +5 8 4 0 7 7 7 7 -5 4 4 0 DROP VIEW v1; DROP TABLE t1; set @@join_cache_level= @tmp_jcl_978479; @@ -2927,9 +2926,9 @@ alias2.col_int_key = alias1.col_int_key WHERE alias1.pk = 58 OR alias1.col_varchar_key = 'o' ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias1 index_merge PRIMARY,col_int_key,col_varchar_key PRIMARY,col_varchar_key 4,4 NULL 2 Using sort_union(PRIMARY,col_varchar_key); Using where; Start temporary -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -1 PRIMARY alias2 ALL col_int_key NULL NULL NULL 12 Range checked for each record (index map: 0x2); End temporary +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 +1 PRIMARY alias1 index_merge PRIMARY,col_int_key,col_varchar_key PRIMARY,col_varchar_key 4,4 NULL 2 Using sort_union(PRIMARY,col_varchar_key); Using where +1 PRIMARY alias2 ALL col_int_key NULL NULL NULL 12 Range checked for each record (index map: 0x2); FirstMatch(t2) SELECT * FROM t2 WHERE (field1) IN (SELECT alias1.col_varchar_nokey AS field1 @@ -3037,7 +3036,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00 Using temporary; Using filesort 1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 5 100.00 Start temporary 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 10.00 Using where; End temporary Warnings: Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1` AS `c1`,'x' AS `c2` from `test`.`t1` semi join (`test`.`t1` left join `test`.`t3` on(`test`.`t1`.`c1` = `test`.`t3`.`c3`)) where `test`.`t1`.`pk` = `test`.`t1`.`pk` order by 'x',`test`.`t1`.`c1` DROP TABLE t1,t2,t3; @@ -3289,8 +3288,7 @@ explain extended SELECT Id FROM t1 WHERE Id in (SELECT t1_Id FROM t2 WHERE t2.col1 IS NULL); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ref col1 col1 5 const 2 100.00 Using index condition; Using where +1 PRIMARY t2 ref col1 col1 5 const 2 50.00 Using index condition; Using where; FirstMatch(t1) Warnings: Note 1003 select 1 AS `Id` from (`test`.`t2`) where `test`.`t2`.`t1_Id` = 1 and `test`.`t2`.`col1` is null DROP TABLE t1, t2; diff --git a/mysql-test/main/subselect_sj.test b/mysql-test/main/subselect_sj.test index e4d02ed666c..3c046c6321c 100644 --- a/mysql-test/main/subselect_sj.test +++ b/mysql-test/main/subselect_sj.test @@ -70,13 +70,13 @@ explain extended select * from t1 where a in (select t10.pk from t10, t12 where --echo subqueries within outer joins go into ON expr. # TODO: psergey: check if case conversions like those are ok (it broke on windows) ---replace_result a A b B +--replace_result a A b B explain explain table table possible possible explain extended select * from t1 left join (t2 A, t2 B) on ( A.a= t1.a and B.a in (select pk from t10)); # TODO: psergey: check if case conversions like those are ok (it broke on windows) --echo t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)" ---replace_result a A b B +--replace_result a A b B explain explain table table possible possible explain extended select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10)); @@ -739,6 +739,7 @@ INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo','ffff','ffff','ffff','ffff','f CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')); +insert into t2 (pk) values (-1),(0); # Test that materialization is skipped for semijoins where materialized # table would contain GEOMETRY or different kinds of BLOB/TEXT columns @@ -1425,7 +1426,7 @@ drop table t1,t2; --echo # BUG#787299: Valgrind complains on a join query with two IN subqueries --echo # create table t1 (a int); -insert into t1 values (1), (2), (3); +insert into t1 values (1), (2), (3),(1000),(2000); create table t2 as select * from t1; select * from t1 A, t1 B where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); @@ -1739,7 +1740,7 @@ DROP TABLE t1,t2,t3; --echo # --echo # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90 ---echo # (Original testcase) +--echo # (Original, slightly modified testcase) --echo # CREATE TABLE t1 (f1 int, f2 int ); @@ -1753,15 +1754,13 @@ INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0); CREATE TABLE t4 ( f2 int, KEY (f2) ); INSERT INTO t4 VALUES (0),(NULL); - -CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ; +INSERT INTO t4 VALUES (0),(NULL),(-1),(-2),(-3); --echo # The following must not have outer joins: explain extended -SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); -SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4 where f2 = 0 or f2 IS NULL); +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4 where f2 = 0 or f2 IS NULL); -drop view v4; drop table t1, t2, t3, t4; --echo # @@ -2249,6 +2248,7 @@ INSERT INTO t1 VALUES CREATE TABLE t2 ( a INT, b INT, KEY(a)) ENGINE=MyISAM; INSERT INTO t2 VALUES (3,20),(2,21),(3,22); +--sorted_result SELECT * FROM t1 AS alias1, t1 AS alias2 WHERE ( alias1.c, alias2.c ) @@ -2292,16 +2292,17 @@ INSERT INTO t1 VALUES CREATE TABLE t2 ( c INT, d INT, KEY(c) ); INSERT INTO t2 VALUES - (1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); + (1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1),(11,11); analyze table t1,t2; explain SELECT a, b, d FROM t1, t2 WHERE ( b, d ) IN - ( SELECT b, d FROM t1, t2 WHERE b = c ); + ( SELECT b, d FROM t1 as t3, t2 as t4 WHERE b = c ); +--sorted_result SELECT a, b, d FROM t1, t2 WHERE ( b, d ) IN - ( SELECT b, d FROM t1, t2 WHERE b = c ); + ( SELECT b, d FROM t1 as t3, t2 as t4 WHERE b = c ); DROP TABLE t1, t2; @@ -2449,6 +2450,7 @@ EXPLAIN SELECT * FROM t1 AS t1_1, t1 AS t1_2 WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 ); +--sorted_result SELECT * FROM t1 AS t1_1, t1 AS t1_2 WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 ); diff --git a/mysql-test/main/subselect_sj2.result b/mysql-test/main/subselect_sj2.result index 6643aa13f83..0a8a680adc0 100644 --- a/mysql-test/main/subselect_sj2.result +++ b/mysql-test/main/subselect_sj2.result @@ -25,11 +25,7 @@ key(b) ); insert into t2 select a, a/2 from t0; insert into t2 select a+10, a+10/2 from t0; -select * from t1; -a b -1 1 -1 1 -2 2 +insert into t1 values (1030,30),(1031,31),(1032,32),(1033,33); select * from t2; a b 0 0 @@ -56,7 +52,7 @@ explain select * from t2 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL b NULL NULL NULL 20 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 7 select * from t2 where b in (select a from t1); a b 1 1 @@ -84,7 +80,7 @@ explain select * from t3 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL b NULL NULL NULL 20 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 7 select * from t3 where b in (select a from t1); a b pk1 pk2 pk3 1 1 1 1 1 @@ -106,11 +102,14 @@ primary key(pk1, pk2) insert into t3 select A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B where B.a <5; +analyze table t3 persistent for all; +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK explain select * from t3 where b in (select a from t0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 ALL b NULL NULL NULL # -1 PRIMARY eq_ref distinct_key distinct_key 4 func # -2 MATERIALIZED t0 ALL NULL NULL NULL NULL # +1 PRIMARY t0 ALL NULL NULL NULL NULL # Using where; Start temporary +1 PRIMARY t3 ref b b 5 test.t0.a # End temporary select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5); a b pk1 pk2 0 0 0 0 @@ -131,20 +130,17 @@ set join_buffer_size= @save_join_buffer_size; set max_heap_table_size= @save_max_heap_table_size; explain select * from t1 where a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 index b b 5 NULL 20 Using index -select * from t1; -a b -1 1 -1 1 -2 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where +1 PRIMARY t2 ref b b 5 test.t1.a 1 Using index; FirstMatch(t1) select * from t1 where a in (select b from t2); a b 1 1 1 1 2 2 drop table t1, t2, t3; +# +# Test join buffering +# set @save_join_buffer_size = @@join_buffer_size; set join_buffer_size= 8192; create table t1 (a int, filler1 binary(200), filler2 binary(200)); @@ -345,7 +341,7 @@ WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan; Start temporary -1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary +1 PRIMARY t2 eq_ref|filter PRIMARY,Population PRIMARY|Population 3|4 test.t1.Country 1 (75%) Using where; End temporary; Using rowid filter 1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where set optimizer_switch=@bug35674_save_optimizer_switch; DROP TABLE t1,t2,t3; @@ -628,7 +624,7 @@ select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where -2 MATERIALIZED t3 index PRIMARY PRIMARY 4 NULL 10 Using index +2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY PRIMARY 4 func 1 Using index drop table t0, t1, t2, t3; create table t1 (a int); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -740,9 +736,8 @@ alter table t3 add primary key(id), add key(a); The following must use loose index scan over t3, key a: explain select count(a) from t2 where a in ( SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index a a 5 NULL 1000 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t3 index a a 5 NULL 30000 Using index +1 PRIMARY t2 index a a 5 NULL 1000 Using where; Using index +1 PRIMARY t3 ref a a 5 test.t2.a 30 Using index; FirstMatch(t2) select count(a) from t2 where a in ( SELECT a FROM t3); count(a) 1000 @@ -770,8 +765,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2) -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t3) select 1 from t2 where c2 in (select 1 from t3, t2) and c1 in (select convert(c6,char(1)) from t2); @@ -839,9 +833,9 @@ explain SELECT * FROM t3 WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias1 const PRIMARY PRIMARY 4 const # Using index +1 PRIMARY alias1 const PRIMARY PRIMARY 4 const # 1 PRIMARY alias2 index f12 f12 7 NULL # Using index; LooseScan -1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index; FirstMatch(alias2) +1 PRIMARY t1 ALL NULL NULL NULL NULL # FirstMatch(alias2) 1 PRIMARY t3 ALL NULL NULL NULL NULL # Using where; Using join buffer (flat, BNL join) SELECT * FROM t3 WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24); @@ -911,9 +905,9 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a WHERE t3.b IN (SELECT b FROM t4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where 1 PRIMARY ALL NULL NULL NULL NULL 2 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 3 DERIVED t1 ALL NULL NULL NULL NULL 1 SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a @@ -950,33 +944,43 @@ INSERT INTO t1 VALUES (11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4), (16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0); CREATE TABLE t2 ( -pk INT, d VARCHAR(1), e INT, +pk INT, d VARCHAR(1), e INT, f int, PRIMARY KEY(pk), KEY(d,e) ) ENGINE=InnoDB; -INSERT INTO t2 VALUES +INSERT INTO t2 (pk,d,e) VALUES (1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5), (6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), (11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), (15,'g',6),(16,'x',7),(17,'f',8); +update t2 set f=pk/2; analyze table t1,t2; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK test.t2 analyze status Engine-independent statistics collected test.t2 analyze status OK +# Original query, changed because of new optimizations explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t2 index PRIMARY,d d 9 NULL 17 Using where; Using index; LooseScan +1 PRIMARY t1 ref a a 5 test.t2.d 1 Using where; Using index; FirstMatch(t2) 1 PRIMARY t1 ref b b 4 test.t2.d 1 -2 MATERIALIZED t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where -2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index +explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 -WHERE a = d AND ( pk < 2 OR d = 'z' ) +WHERE a = d AND ( pk < 2 OR d = 'z' ) and f > 0 +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where; Start temporary +1 PRIMARY t1 ref a a 5 test.t2.d 1 Using where; Using index +1 PRIMARY t1 ref b b 4 test.t2.d 1 End temporary +SELECT * FROM t1 WHERE b IN ( +SELECT d FROM t2, t1 +WHERE a = d AND ( pk < 2 OR d = 'z' ) and f > 0 ); a b c Warnings: @@ -1224,10 +1228,10 @@ t1_pk1 t1_pk2 t3_i t3_c explain SELECT * FROM t1, t3 WHERE t3_c IN ( SELECT t1_pk2 FROM t4, t2 WHERE t2_c = t1_pk2 AND t2_i >= t3_i ) AND ( t1_pk1 = 'POL' ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ref PRIMARY PRIMARY 5 const 1 Using where; Using index -1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Start temporary -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -1 PRIMARY t4 index NULL PRIMARY 59 NULL 2 Using where; Using index; End temporary +1 PRIMARY t1 ref PRIMARY PRIMARY 5 const 1 Using where +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t3) DROP TABLE t1,t2,t3,t4; # # MDEV-6263: Wrong result when using IN subquery with order by @@ -1345,9 +1349,9 @@ WHERE T3_0_.t3idref= 1 ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY T3_0_ ref PRIMARY,FK_T3_T2Id PRIMARY 8 const 3 Using index; Start temporary +1 PRIMARY T3_0_ ref PRIMARY,FK_T3_T2Id PRIMARY 8 const 3 Start temporary 1 PRIMARY T2_1_ eq_ref PRIMARY,FK_T2_T1Id PRIMARY 8 test.T3_0_.t2idref 1 -1 PRIMARY T1_1_ eq_ref PRIMARY PRIMARY 8 test.T2_1_.t1idref 1 Using index +1 PRIMARY T1_1_ eq_ref PRIMARY PRIMARY 8 test.T2_1_.t1idref 1 1 PRIMARY T2_0_ ref FK_T2_T1Id FK_T2_T1Id 8 test.T2_1_.t1idref 1 Using index; End temporary drop table t3,t2,t1; set optimizer_search_depth=@tmp7474; diff --git a/mysql-test/main/subselect_sj2.test b/mysql-test/main/subselect_sj2.test index 5b9ec409c5d..4ccdcc50a38 100644 --- a/mysql-test/main/subselect_sj2.test +++ b/mysql-test/main/subselect_sj2.test @@ -2,13 +2,15 @@ # DuplicateElimination strategy test # +--source include/have_innodb.inc +--source include/have_sequence.inc + set @innodb_stats_persistent_save= @@innodb_stats_persistent; set @innodb_stats_persistent_sample_pages_save= @@innodb_stats_persistent_sample_pages; set global innodb_stats_persistent= 1; set global innodb_stats_persistent_sample_pages=100; ---source include/have_innodb.inc set @subselect_sj2_tmp= @@optimizer_switch; set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; @@ -48,7 +50,7 @@ create table t2 ( insert into t2 select a, a/2 from t0; insert into t2 select a+10, a+10/2 from t0; -select * from t1; +insert into t1 values (1030,30),(1031,31),(1032,32),(1033,33); select * from t2; explain select * from t2 where b in (select a from t1); select * from t2 where b in (select a from t1); @@ -87,6 +89,7 @@ insert into t3 select A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B where B.a <5; +analyze table t3 persistent for all; --replace_column 9 # explain select * from t3 where b in (select a from t0); select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5); @@ -96,15 +99,15 @@ set max_heap_table_size= @save_max_heap_table_size; # O2I join orders, with shortcutting: explain select * from t1 where a in (select b from t2); -select * from t1; select * from t1 where a in (select b from t2); drop table t1, t2, t3; # (no need for anything in range/index_merge/DS-MRR) -# -# Test join buffering -# +--echo # +--echo # Test join buffering +--echo # + set @save_join_buffer_size = @@join_buffer_size; set join_buffer_size= 8192; @@ -255,6 +258,7 @@ INSERT INTO t3 VALUES # Disable materialization to avoid races between query plans set @bug35674_save_optimizer_switch=@@optimizer_switch; set optimizer_switch='materialization=off'; + EXPLAIN SELECT Name FROM t2 WHERE t2.Code IN (SELECT Country FROM t1 WHERE Population > 5000000) @@ -1121,26 +1125,35 @@ INSERT INTO t1 VALUES (16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0); CREATE TABLE t2 ( - pk INT, d VARCHAR(1), e INT, + pk INT, d VARCHAR(1), e INT, f int, PRIMARY KEY(pk), KEY(d,e) ) ENGINE=InnoDB; -INSERT INTO t2 VALUES +INSERT INTO t2 (pk,d,e) VALUES (1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5), (6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), (11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), (15,'g',6),(16,'x',7),(17,'f',8); +update t2 set f=pk/2; analyze table t1,t2; +--echo # Original query, changed because of new optimizations explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); + +explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 - WHERE a = d AND ( pk < 2 OR d = 'z' ) + WHERE a = d AND ( pk < 2 OR d = 'z' ) and f > 0 +); + +SELECT * FROM t1 WHERE b IN ( + SELECT d FROM t2, t1 + WHERE a = d AND ( pk < 2 OR d = 'z' ) and f > 0 ); DROP TABLE t1, t2; @@ -1311,8 +1324,6 @@ SELECT * FROM t1 WHERE 9 IN ( SELECT b FROM t2 WHERE 1 IN ( SELECT MIN(c) FROM t DROP TABLE t1,t2,t3; ---source include/have_innodb.inc - --disable_warnings DROP TABLE IF EXISTS t1,t2,t3,t4; --enable_warnings diff --git a/mysql-test/main/subselect_sj2_jcl6.result b/mysql-test/main/subselect_sj2_jcl6.result index 83abb68ca51..c3e3a77c679 100644 --- a/mysql-test/main/subselect_sj2_jcl6.result +++ b/mysql-test/main/subselect_sj2_jcl6.result @@ -36,11 +36,7 @@ key(b) ); insert into t2 select a, a/2 from t0; insert into t2 select a+10, a+10/2 from t0; -select * from t1; -a b -1 1 -1 1 -2 2 +insert into t1 values (1030,30),(1031,31),(1032,32),(1033,33); select * from t2; a b 0 0 @@ -66,8 +62,7 @@ a b explain select * from t2 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL b NULL NULL NULL 20 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where; FirstMatch(t2); Using join buffer (flat, BNL join) select * from t2 where b in (select a from t1); a b 1 1 @@ -94,8 +89,7 @@ test.t3 analyze status OK explain select * from t3 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL b NULL NULL NULL 20 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where; FirstMatch(t3); Using join buffer (flat, BNL join) select * from t3 where b in (select a from t1); a b pk1 pk2 pk3 1 1 1 1 1 @@ -117,11 +111,14 @@ primary key(pk1, pk2) insert into t3 select A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B where B.a <5; +analyze table t3 persistent for all; +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK explain select * from t3 where b in (select a from t0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 ALL b NULL NULL NULL # -1 PRIMARY eq_ref distinct_key distinct_key 4 func # -2 MATERIALIZED t0 ALL NULL NULL NULL NULL # +1 PRIMARY t0 ALL NULL NULL NULL NULL # Using where; Start temporary +1 PRIMARY t3 ref b b 5 test.t0.a # End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5); a b pk1 pk2 0 0 0 0 @@ -142,20 +139,17 @@ set join_buffer_size= @save_join_buffer_size; set max_heap_table_size= @save_max_heap_table_size; explain select * from t1 where a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 index b b 5 NULL 20 Using index -select * from t1; -a b -1 1 -1 1 -2 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where +1 PRIMARY t2 ref b b 5 test.t1.a 1 Using index; FirstMatch(t1) select * from t1 where a in (select b from t2); a b 1 1 1 1 2 2 drop table t1, t2, t3; +# +# Test join buffering +# set @save_join_buffer_size = @@join_buffer_size; set join_buffer_size= 8192; create table t1 (a int, filler1 binary(200), filler2 binary(200)); @@ -172,8 +166,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z from t1 ot where a in (select a from t2 it); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot ALL NULL NULL NULL NULL 32 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED it ALL NULL NULL NULL NULL 22 +1 PRIMARY it ALL NULL NULL NULL NULL 22 Using where; FirstMatch(ot); Using join buffer (flat, BNL join) select a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z from t1 ot where a in (select a from t2 it); @@ -197,16 +190,15 @@ a mid(filler1, 1,10) Z 16 filler1234 1 17 filler1234 1 18 filler1234 1 -19 filler1234 1 2 duplicate 1 18 duplicate 1 +19 filler1234 1 explain select a, mid(filler1, 1,10), length(filler1)=length(filler2) from t2 ot where a in (select a from t1 it); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot ALL NULL NULL NULL NULL 22 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED it ALL NULL NULL NULL NULL 32 +1 PRIMARY it ALL NULL NULL NULL NULL 32 Using where; FirstMatch(ot); Using join buffer (flat, BNL join) select a, mid(filler1, 1,10), length(filler1)=length(filler2) from t2 ot where a in (select a from t1 it); @@ -230,8 +222,8 @@ a mid(filler1, 1,10) length(filler1)=length(filler2) 16 filler1234 1 17 filler1234 1 18 filler1234 1 -19 filler1234 1 3 duplicate 1 +19 filler1234 1 19 duplicate 1 insert into t1 select a+20, 'filler123456', 'filler123456' from t0; insert into t1 select a+20, 'filler123456', 'filler123456' from t0; @@ -356,7 +348,7 @@ WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan; Start temporary -1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 PRIMARY t2 eq_ref|filter PRIMARY,Population PRIMARY|Population 3|4 test.t1.Country 1 (75%) Using where; End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter 1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan set optimizer_switch=@bug35674_save_optimizer_switch; DROP TABLE t1,t2,t3; @@ -641,7 +633,7 @@ select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 1 PRIMARY t2 hash_ALL NULL #hash#$hj 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH join) -2 MATERIALIZED t3 index PRIMARY PRIMARY 4 NULL 10 Using index +2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY PRIMARY 4 func 1 Using index drop table t0, t1, t2, t3; create table t1 (a int); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -753,9 +745,8 @@ alter table t3 add primary key(id), add key(a); The following must use loose index scan over t3, key a: explain select count(a) from t2 where a in ( SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index a a 5 NULL 1000 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t3 index a a 5 NULL 30000 Using index +1 PRIMARY t2 index a a 5 NULL 1000 Using where; Using index +1 PRIMARY t3 ref a a 5 test.t2.a 30 Using index; FirstMatch(t2) select count(a) from t2 where a in ( SELECT a FROM t3); count(a) 1000 @@ -783,8 +774,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2); Using join buffer (incremental, BNL join) -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t3); Using join buffer (incremental, BNL join) select 1 from t2 where c2 in (select 1 from t3, t2) and c1 in (select convert(c6,char(1)) from t2); @@ -852,9 +842,9 @@ explain SELECT * FROM t3 WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias1 const PRIMARY PRIMARY 4 const # Using index +1 PRIMARY alias1 const PRIMARY PRIMARY 4 const # 1 PRIMARY alias2 index f12 f12 7 NULL # Using index; LooseScan -1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index; FirstMatch(alias2) +1 PRIMARY t1 ALL NULL NULL NULL NULL # FirstMatch(alias2) 1 PRIMARY t3 ALL NULL NULL NULL NULL # Using where; Using join buffer (flat, BNL join) SELECT * FROM t3 WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24); @@ -924,9 +914,9 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a WHERE t3.b IN (SELECT b FROM t4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t2 hash_ALL NULL #hash#$hj 4 test.t3.a 1 Using where; Using join buffer (flat, BNLH join) 1 PRIMARY ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join) +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 3 DERIVED t1 ALL NULL NULL NULL NULL 1 SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a @@ -963,33 +953,43 @@ INSERT INTO t1 VALUES (11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4), (16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0); CREATE TABLE t2 ( -pk INT, d VARCHAR(1), e INT, +pk INT, d VARCHAR(1), e INT, f int, PRIMARY KEY(pk), KEY(d,e) ) ENGINE=InnoDB; -INSERT INTO t2 VALUES +INSERT INTO t2 (pk,d,e) VALUES (1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5), (6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), (11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), (15,'g',6),(16,'x',7),(17,'f',8); +update t2 set f=pk/2; analyze table t1,t2; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK test.t2 analyze status Engine-independent statistics collected test.t2 analyze status OK +# Original query, changed because of new optimizations explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t2 index PRIMARY,d d 9 NULL 17 Using where; Using index; LooseScan +1 PRIMARY t1 ref a a 5 test.t2.d 1 Using where; Using index; FirstMatch(t2) 1 PRIMARY t1 ref b b 4 test.t2.d 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -2 MATERIALIZED t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where -2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index +explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 -WHERE a = d AND ( pk < 2 OR d = 'z' ) +WHERE a = d AND ( pk < 2 OR d = 'z' ) and f > 0 +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where; Start temporary +1 PRIMARY t1 ref a a 5 test.t2.d 1 Using where; Using index +1 PRIMARY t1 ref b b 4 test.t2.d 1 End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +SELECT * FROM t1 WHERE b IN ( +SELECT d FROM t2, t1 +WHERE a = d AND ( pk < 2 OR d = 'z' ) and f > 0 ); a b c Warnings: @@ -1237,10 +1237,10 @@ t1_pk1 t1_pk2 t3_i t3_c explain SELECT * FROM t1, t3 WHERE t3_c IN ( SELECT t1_pk2 FROM t4, t2 WHERE t2_c = t1_pk2 AND t2_i >= t3_i ) AND ( t1_pk1 = 'POL' ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ref PRIMARY PRIMARY 5 const 1 Using where; Using index -1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Start temporary; Using join buffer (flat, BNL join) -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) -1 PRIMARY t4 hash_index NULL #hash#$hj:PRIMARY 54:59 test.t3.t3_c 2 Using where; Using index; End temporary; Using join buffer (incremental, BNLH join) +1 PRIMARY t1 ref PRIMARY PRIMARY 5 const 1 Using where +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t3); Using join buffer (incremental, BNL join) DROP TABLE t1,t2,t3,t4; # # MDEV-6263: Wrong result when using IN subquery with order by @@ -1358,9 +1358,9 @@ WHERE T3_0_.t3idref= 1 ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY T3_0_ ref PRIMARY,FK_T3_T2Id PRIMARY 8 const 3 Using index; Start temporary +1 PRIMARY T3_0_ ref PRIMARY,FK_T3_T2Id PRIMARY 8 const 3 Start temporary 1 PRIMARY T2_1_ eq_ref PRIMARY,FK_T2_T1Id PRIMARY 8 test.T3_0_.t2idref 1 Using join buffer (flat, BKA join); Key-ordered scan -1 PRIMARY T1_1_ eq_ref PRIMARY PRIMARY 8 test.T2_1_.t1idref 1 Using index +1 PRIMARY T1_1_ eq_ref PRIMARY PRIMARY 8 test.T2_1_.t1idref 1 Using join buffer (incremental, BKA join); Key-ordered scan 1 PRIMARY T2_0_ ref FK_T2_T1Id FK_T2_T1Id 8 test.T2_1_.t1idref 1 Using index; End temporary drop table t3,t2,t1; set optimizer_search_depth=@tmp7474; @@ -1439,10 +1439,9 @@ SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b WHERE c IN (SELECT t4.b FROM t4 JOIN t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t3); Using join buffer (incremental, BNL join) 1 PRIMARY t1 ref b b 4 test.t3.b 1 Using index -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b WHERE c IN (SELECT t4.b FROM t4 JOIN t2); b c @@ -1460,18 +1459,19 @@ INSERT INTO t2 VALUES (8); CREATE TABLE t3 (pk int PRIMARY KEY, a int); INSERT INTO t3 VALUES (1, 6), (2, 8); CREATE TABLE t4 (b int) ENGINE=InnoDB; -INSERT INTO t4 VALUES (2); +INSERT INTO t4 VALUES (2),(88),(99); +insert into t2 select seq from seq_100_to_200; set @tmp_optimizer_switch=@@optimizer_switch; SET optimizer_switch = 'semijoin_with_cache=on'; SET join_cache_level = 2; EXPLAIN SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 1 Using where -2 MATERIALIZED t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL # +1 PRIMARY t2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join) +1 PRIMARY eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED t4 ALL NULL NULL NULL NULL # Using where +2 MATERIALIZED t3 eq_ref PRIMARY PRIMARY 4 test.t4.b # SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk); pk a b 1 6 8 @@ -1493,8 +1493,7 @@ EXPLAIN SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a); a b v v diff --git a/mysql-test/main/subselect_sj2_jcl6.test b/mysql-test/main/subselect_sj2_jcl6.test index a0c8a6c0f04..1001a213768 100644 --- a/mysql-test/main/subselect_sj2_jcl6.test +++ b/mysql-test/main/subselect_sj2_jcl6.test @@ -66,13 +66,16 @@ INSERT INTO t2 VALUES (8); CREATE TABLE t3 (pk int PRIMARY KEY, a int); INSERT INTO t3 VALUES (1, 6), (2, 8); CREATE TABLE t4 (b int) ENGINE=InnoDB; -INSERT INTO t4 VALUES (2); +INSERT INTO t4 VALUES (2),(88),(99); + +insert into t2 select seq from seq_100_to_200; set @tmp_optimizer_switch=@@optimizer_switch; SET optimizer_switch = 'semijoin_with_cache=on'; SET join_cache_level = 2; +--replace_column 9 # EXPLAIN SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk); SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk); diff --git a/mysql-test/main/subselect_sj2_mat.result b/mysql-test/main/subselect_sj2_mat.result index 5d7e7d49da2..a04e6333b07 100644 --- a/mysql-test/main/subselect_sj2_mat.result +++ b/mysql-test/main/subselect_sj2_mat.result @@ -27,11 +27,7 @@ key(b) ); insert into t2 select a, a/2 from t0; insert into t2 select a+10, a+10/2 from t0; -select * from t1; -a b -1 1 -1 1 -2 2 +insert into t1 values (1030,30),(1031,31),(1032,32),(1033,33); select * from t2; a b 0 0 @@ -58,7 +54,7 @@ explain select * from t2 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL b NULL NULL NULL 20 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 7 select * from t2 where b in (select a from t1); a b 1 1 @@ -86,7 +82,7 @@ explain select * from t3 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL b NULL NULL NULL 20 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 7 select * from t3 where b in (select a from t1); a b pk1 pk2 pk3 1 1 1 1 1 @@ -108,11 +104,14 @@ primary key(pk1, pk2) insert into t3 select A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B where B.a <5; +analyze table t3 persistent for all; +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK explain select * from t3 where b in (select a from t0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 ALL b NULL NULL NULL # -1 PRIMARY eq_ref distinct_key distinct_key 4 func # -2 MATERIALIZED t0 ALL NULL NULL NULL NULL # +1 PRIMARY t0 ALL NULL NULL NULL NULL # Using where; Start temporary +1 PRIMARY t3 ref b b 5 test.t0.a # End temporary select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5); a b pk1 pk2 0 0 0 0 @@ -133,20 +132,17 @@ set join_buffer_size= @save_join_buffer_size; set max_heap_table_size= @save_max_heap_table_size; explain select * from t1 where a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 index b b 5 NULL 20 Using index -select * from t1; -a b -1 1 -1 1 -2 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where +1 PRIMARY t2 ref b b 5 test.t1.a 1 Using index; FirstMatch(t1) select * from t1 where a in (select b from t2); a b 1 1 1 1 2 2 drop table t1, t2, t3; +# +# Test join buffering +# set @save_join_buffer_size = @@join_buffer_size; set join_buffer_size= 8192; create table t1 (a int, filler1 binary(200), filler2 binary(200)); @@ -347,7 +343,7 @@ WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan; Start temporary -1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary +1 PRIMARY t2 eq_ref|filter PRIMARY,Population PRIMARY|Population 3|4 test.t1.Country 1 (75%) Using where; End temporary; Using rowid filter 1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where set optimizer_switch=@bug35674_save_optimizer_switch; DROP TABLE t1,t2,t3; @@ -630,7 +626,7 @@ select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where -2 MATERIALIZED t3 index PRIMARY PRIMARY 4 NULL 10 Using index +2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY PRIMARY 4 func 1 Using index drop table t0, t1, t2, t3; create table t1 (a int); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -742,9 +738,8 @@ alter table t3 add primary key(id), add key(a); The following must use loose index scan over t3, key a: explain select count(a) from t2 where a in ( SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index a a 5 NULL 1000 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t3 index a a 5 NULL 30000 Using index +1 PRIMARY t2 index a a 5 NULL 1000 Using where; Using index +1 PRIMARY t3 ref a a 5 test.t2.a 30 Using index; FirstMatch(t2) select count(a) from t2 where a in ( SELECT a FROM t3); count(a) 1000 @@ -772,8 +767,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2) -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t3) select 1 from t2 where c2 in (select 1 from t3, t2) and c1 in (select convert(c6,char(1)) from t2); @@ -841,9 +835,9 @@ explain SELECT * FROM t3 WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias1 const PRIMARY PRIMARY 4 const # Using index +1 PRIMARY alias1 const PRIMARY PRIMARY 4 const # 1 PRIMARY alias2 index f12 f12 7 NULL # Using index; LooseScan -1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index; FirstMatch(alias2) +1 PRIMARY t1 ALL NULL NULL NULL NULL # FirstMatch(alias2) 1 PRIMARY t3 ALL NULL NULL NULL NULL # Using where; Using join buffer (flat, BNL join) SELECT * FROM t3 WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24); @@ -913,9 +907,9 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a WHERE t3.b IN (SELECT b FROM t4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where 1 PRIMARY ALL NULL NULL NULL NULL 2 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 3 DERIVED t1 ALL NULL NULL NULL NULL 1 SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a @@ -952,33 +946,43 @@ INSERT INTO t1 VALUES (11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4), (16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0); CREATE TABLE t2 ( -pk INT, d VARCHAR(1), e INT, +pk INT, d VARCHAR(1), e INT, f int, PRIMARY KEY(pk), KEY(d,e) ) ENGINE=InnoDB; -INSERT INTO t2 VALUES +INSERT INTO t2 (pk,d,e) VALUES (1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5), (6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), (11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), (15,'g',6),(16,'x',7),(17,'f',8); +update t2 set f=pk/2; analyze table t1,t2; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK test.t2 analyze status Engine-independent statistics collected test.t2 analyze status OK +# Original query, changed because of new optimizations explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t2 index PRIMARY,d d 9 NULL 17 Using where; Using index; LooseScan +1 PRIMARY t1 ref a a 5 test.t2.d 1 Using where; Using index; FirstMatch(t2) 1 PRIMARY t1 ref b b 4 test.t2.d 1 -2 MATERIALIZED t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where -2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index +explain SELECT * FROM t1 WHERE b IN ( SELECT d FROM t2, t1 -WHERE a = d AND ( pk < 2 OR d = 'z' ) +WHERE a = d AND ( pk < 2 OR d = 'z' ) and f > 0 +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where; Start temporary +1 PRIMARY t1 ref a a 5 test.t2.d 1 Using where; Using index +1 PRIMARY t1 ref b b 4 test.t2.d 1 End temporary +SELECT * FROM t1 WHERE b IN ( +SELECT d FROM t2, t1 +WHERE a = d AND ( pk < 2 OR d = 'z' ) and f > 0 ); a b c Warnings: @@ -1226,10 +1230,10 @@ t1_pk1 t1_pk2 t3_i t3_c explain SELECT * FROM t1, t3 WHERE t3_c IN ( SELECT t1_pk2 FROM t4, t2 WHERE t2_c = t1_pk2 AND t2_i >= t3_i ) AND ( t1_pk1 = 'POL' ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ref PRIMARY PRIMARY 5 const 1 Using where; Using index -1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Start temporary -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -1 PRIMARY t4 index NULL PRIMARY 59 NULL 2 Using where; Using index; End temporary +1 PRIMARY t1 ref PRIMARY PRIMARY 5 const 1 Using where +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t3) DROP TABLE t1,t2,t3,t4; # # MDEV-6263: Wrong result when using IN subquery with order by @@ -1347,9 +1351,9 @@ WHERE T3_0_.t3idref= 1 ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY T3_0_ ref PRIMARY,FK_T3_T2Id PRIMARY 8 const 3 Using index; Start temporary +1 PRIMARY T3_0_ ref PRIMARY,FK_T3_T2Id PRIMARY 8 const 3 Start temporary 1 PRIMARY T2_1_ eq_ref PRIMARY,FK_T2_T1Id PRIMARY 8 test.T3_0_.t2idref 1 -1 PRIMARY T1_1_ eq_ref PRIMARY PRIMARY 8 test.T2_1_.t1idref 1 Using index +1 PRIMARY T1_1_ eq_ref PRIMARY PRIMARY 8 test.T2_1_.t1idref 1 1 PRIMARY T2_0_ ref FK_T2_T1Id FK_T2_T1Id 8 test.T2_1_.t1idref 1 Using index; End temporary drop table t3,t2,t1; set optimizer_search_depth=@tmp7474; @@ -1511,8 +1515,7 @@ t3.sack_id = 33479 AND t3.kit_id = 6; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 5 Using index 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.cat_id 1 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t4 index cat_id cat_id 4 NULL 19 Using index +1 PRIMARY t4 ref cat_id cat_id 4 test.t3.cat_id 1 Using index; FirstMatch(t1) SELECT count(*) FROM t1, t3 WHERE t1.cat_id = t3.cat_id AND t3.cat_id IN (SELECT cat_id FROM t4) AND @@ -1527,8 +1530,7 @@ t3.sack_id = 33479 AND t3.kit_id = 6; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 5 Using index 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.cat_id 1 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -2 MATERIALIZED t2 index cat_id cat_id 4 NULL 19 Using index +1 PRIMARY t2 ref cat_id cat_id 4 test.t3.cat_id 2 Using where; Using index; FirstMatch(t1) SELECT count(*) FROM t1, t3 WHERE t1.cat_id = t3.cat_id AND t3.cat_id IN (SELECT cat_id FROM t2) AND @@ -1557,7 +1559,7 @@ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary 1 PRIMARY t1 ref idx idx 2 test.t4.a4 1 100.00 Using index -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 16.67 End temporary; Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(`test`.`t2`.`a2` = `test`.`t4`.`a4`) where `test`.`t4`.`b4` = `test`.`t4`.`a4` and `test`.`t1`.`b1` = `test`.`t4`.`a4` @@ -1575,7 +1577,7 @@ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary 1 PRIMARY t1 ref idx idx 2 test.t4.a4 1 100.00 Using index -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 16.67 End temporary; Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(`test`.`t2`.`a2` = `test`.`t4`.`a4`) where `test`.`t4`.`b4` = `test`.`t4`.`a4` and `test`.`t1`.`b1` = `test`.`t4`.`a4` @@ -1610,7 +1612,7 @@ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary; Using join buffer (flat, BNL join) -1 PRIMARY t3 ALL NULL NULL NULL NULL 10 100.00 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 10 5.00 Using where; End temporary; Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(`test`.`t2`.`c2` = `test`.`t1`.`c1` or `test`.`t1`.`c1` > 'z') where `test`.`t4`.`c4` = `test`.`t1`.`c1` and `test`.`t3`.`c3` = `test`.`t1`.`c1` @@ -1714,11 +1716,10 @@ i explain extended select * from t1 where (rand() < 0) and i in (select i from t2); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 10 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join (`test`.`t2`) where rand() < 0 +Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`i` = `test`.`t1`.`i` and rand() < 0 drop table t1,t2; set optimizer_switch=@save_optimizer_switch; # @@ -1727,7 +1728,13 @@ set optimizer_switch=@save_optimizer_switch; CREATE TABLE t1 (f1 varchar(8), KEY(f1)) ENGINE=InnoDB; INSERT INTO t1 VALUES ('qux'),('foo'); CREATE TABLE t2 (f2 varchar(8)) ENGINE=InnoDB; -INSERT INTO t2 VALUES ('bar'),('foo'),('qux'); +INSERT INTO t2 VALUES ('bar'),('foo'),('qux'),('qq1'),('qq2'); +analyze table t1,t2 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK SELECT f1 FROM t1 WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' ) HAVING f1 != 'foo' @@ -1739,9 +1746,8 @@ WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' ) HAVING f1 != 'foo' ORDER BY f1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range f1 f1 11 NULL 2 Using where; Using index -1 PRIMARY eq_ref distinct_key distinct_key 11 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY t1 range f1 f1 11 NULL 2 Using where; Using index; Using temporary; Using filesort +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) DROP TABLE t1,t2; # # MDEV-16225: wrong resultset from query with semijoin=on @@ -1779,7 +1785,7 @@ OR (t.id IN (0,4,12,13,1,10,3,11)) ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t index PRIMARY PRIMARY 4 NULL 114 Using where; Using index +1 PRIMARY t ALL PRIMARY NULL NULL NULL 114 Using where 2 MATERIALIZED A ALL PRIMARY NULL NULL NULL 114 2 MATERIALIZED eq_ref distinct_key distinct_key 67 func 1 3 MATERIALIZED B range PRIMARY PRIMARY 4 NULL 8 Using where @@ -1838,16 +1844,15 @@ explain SELECT t2.id FROM t2,t1 WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 30 Using index -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.id 1 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -2 MATERIALIZED t3 ALL NULL NULL NULL NULL 14 -2 MATERIALIZED t1 eq_ref PRIMARY PRIMARY 4 test.t3.id 1 Using index +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where; Start temporary +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t3.ref_id 1 Using where; Using index +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.id 1 Using index; End temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.ref_id 1 Using where; Using index SELECT t2.id FROM t2,t1 WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; id -10 11 +10 set optimizer_switch='materialization=off'; SELECT t2.id FROM t2,t1 WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; @@ -1944,20 +1949,16 @@ AND t3.id_product IN (SELECT id_product FROM t2 t2_3 WHERE t2_3.id_t2 = 18 OR t2 AND t3.id_product IN (SELECT id_product FROM t2 t2_4 WHERE t2_4.id_t2 = 34 OR t2_4.id_t2 = 23) AND t3.id_product IN (SELECT id_product FROM t2 t2_5 WHERE t2_5.id_t2 = 29 OR t2_5.id_t2 = 28 OR t2_5.id_t2 = 26); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 index PRIMARY PRIMARY 4 NULL 18 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -1 PRIMARY t5 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t2_2 ref id_t2,id_product id_t2 5 const 12 Using where; Start temporary +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t2_2.id_product 1 Using where; Using index; End temporary 1 PRIMARY t4 eq_ref PRIMARY PRIMARY 8 test.t3.id_product,const 1 Using where; Using index 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY t2_3 range id_t2,id_product id_t2 5 NULL 33 Using index condition; Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_5 range id_t2,id_product id_t2 5 NULL 31 Using index condition; Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t5 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t1 index NULL PRIMARY 8 NULL 73 Using where; Using index; Using join buffer (flat, BNL join) -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -3 MATERIALIZED t2_2 ref id_t2,id_product id_t2 5 const 12 2 MATERIALIZED t2_1 ALL id_t2,id_product NULL NULL NULL 223 Using where -4 MATERIALIZED t2_3 range id_t2,id_product id_t2 5 NULL 33 Using index condition; Using where -5 MATERIALIZED t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where -6 MATERIALIZED t2_5 range id_t2,id_product id_t2 5 NULL 31 Using index condition; Using where set optimizer_switch='rowid_filter=default'; drop table t1,t2,t3,t4,t5; set global innodb_stats_persistent= @innodb_stats_persistent_save; diff --git a/mysql-test/main/subselect_sj2_mat.test b/mysql-test/main/subselect_sj2_mat.test index 4b768652670..e38418f4798 100644 --- a/mysql-test/main/subselect_sj2_mat.test +++ b/mysql-test/main/subselect_sj2_mat.test @@ -300,7 +300,8 @@ set optimizer_switch=@save_optimizer_switch; CREATE TABLE t1 (f1 varchar(8), KEY(f1)) ENGINE=InnoDB; INSERT INTO t1 VALUES ('qux'),('foo'); CREATE TABLE t2 (f2 varchar(8)) ENGINE=InnoDB; -INSERT INTO t2 VALUES ('bar'),('foo'),('qux'); +INSERT INTO t2 VALUES ('bar'),('foo'),('qux'),('qq1'),('qq2'); +analyze table t1,t2 persistent for all; let $q= SELECT f1 FROM t1 diff --git a/mysql-test/main/subselect_sj_jcl6.result b/mysql-test/main/subselect_sj_jcl6.result index 6efa3fc12b1..9028b1c8aac 100644 --- a/mysql-test/main/subselect_sj_jcl6.result +++ b/mysql-test/main/subselect_sj_jcl6.result @@ -87,24 +87,24 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where `test`.`t12`.`pk` = `test`.`t10`.`a` and `test`.`t10`.`pk` = `test`.`t1`.`a` subqueries within outer joins go into ON expr. -explAin extended +explain extended select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10)); -id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA +id select_type table type possible_keys key key_len ref rows filtered ExtrA 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 1 PRIMARY A ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (flAt, BNL join) 1 PRIMARY B ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (incrementAl, BNL join) -2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index +2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(`test`.`A`.`A` = `test`.`t1`.`A` And (`test`.`B`.`A`,`test`.`B`.`A` in ( (/* select#2 */ select `test`.`t10`.`pk` from `test`.`t10` ), (`test`.`B`.`A` in on distinct_key where `test`.`B`.`A` = ``.`pk`)))) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(`test`.`A`.`A` = `test`.`t1`.`A` And (`test`.`B`.`A`,(((`test`.`B`.`A`) in t10 on PRIMARY)))) where 1 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)" -explAin extended +explain extended select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10)); -id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA +id select_type table type possible_keys key key_len ref rows filtered ExtrA 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (flAt, BNL join) -2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index +2 DEPENDENT SUBQUERY t10 unique_suBquery PRIMARY PRIMARY 4 func 1 100.00 Using index Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`A` = `test`.`t1`.`A` And (`test`.`t1`.`A`,`test`.`t1`.`A` in ( (/* select#2 */ select `test`.`t10`.`pk` from `test`.`t10` ), (`test`.`t1`.`A` in on distinct_key where `test`.`t1`.`A` = ``.`pk`)))) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`A` = `test`.`t1`.`A` And (`test`.`t1`.`A`,(((`test`.`t2`.`A`) in t10 on PRIMARY)))) where 1 set @save_join_buffer_size=@@join_buffer_size; set join_buffer_size=8*1024; we shouldn't flatten if we're going to get a join of > MAX_TABLES. @@ -171,26 +171,26 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY s47 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) 1 PRIMARY s48 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) 1 PRIMARY s49 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m00 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY m01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY m02 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m03 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m04 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m05 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m06 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m07 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m08 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m09 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m10 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m11 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m12 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m13 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m14 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m15 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m16 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m17 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m18 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) -2 DEPENDENT SUBQUERY m19 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m00 ALL NULL NULL NULL NULL 3 +2 MATERIALIZED m01 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join) +2 MATERIALIZED m02 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m03 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m04 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m05 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m06 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m07 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m08 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m09 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m10 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m11 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m12 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m13 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m14 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m15 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m16 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m17 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m18 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +2 MATERIALIZED m19 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10)) where t1.a < 5; @@ -355,8 +355,8 @@ WHERE PNUM IN (SELECT PNUM FROM PROJ)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY STAFF ALL NULL NULL NULL NULL 5 -1 PRIMARY PROJ ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join) -1 PRIMARY WORKS ALL NULL NULL NULL NULL 12 Using where; FirstMatch(STAFF); Using join buffer (incremental, BNL join) +1 PRIMARY PROJ ALL NULL NULL NULL NULL 6 Start temporary; Using join buffer (flat, BNL join) +1 PRIMARY WORKS ALL NULL NULL NULL NULL 12 Using where; End temporary; Using join buffer (incremental, BNL join) SELECT EMPNUM, EMPNAME FROM STAFF WHERE EMPNUM IN @@ -513,7 +513,7 @@ EXPLAIN EXTENDED SELECT vkey FROM t0 WHERE pk IN id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t0 ALL PRIMARY NULL NULL NULL 5 100.00 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t0.pk 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 2 100.00 Using index; FirstMatch(t1) +1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 1 100.00 Using index; FirstMatch(t1) Warnings: Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where `test`.`t1`.`pk` = `test`.`t0`.`pk` and `test`.`t2`.`vkey` = `test`.`t1`.`vnokey` SELECT vkey FROM t0 WHERE pk IN @@ -813,13 +813,13 @@ PRIMARY KEY (pk) INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff', 'ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')); CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')); +insert into t2 (pk) values (-1),(0); EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 11 func,func 1 100.00 -2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan +1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`pk` > 0 +Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b` and `test`.`t2`.`pk` > 0 SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); pk 2 @@ -985,10 +985,9 @@ FROM t1 WHERE `varchar_nokey` < 'n' XOR `pk` ) ; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 -2 MATERIALIZED t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where +1 PRIMARY t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 100.00 Using where; FirstMatch(t2); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan Warnings: -Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`varchar_nokey` = `test`.`t1`.`varchar_key` and (`test`.`t1`.`varchar_key` < 'n' xor `test`.`t1`.`pk`) +Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where `test`.`t1`.`varchar_key` = `test`.`t2`.`varchar_nokey` and `test`.`t1`.`varchar_nokey` = `test`.`t2`.`varchar_nokey` and (`test`.`t2`.`varchar_nokey` < 'n' xor `test`.`t1`.`pk`) SELECT varchar_nokey FROM t2 WHERE ( `varchar_nokey` , `varchar_nokey` ) IN ( @@ -1067,10 +1066,8 @@ AND t1.val IN (SELECT t3.val FROM t3 WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%'); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 -1 PRIMARY eq_ref distinct_key distinct_key 13 func 1 -1 PRIMARY eq_ref distinct_key distinct_key 13 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where -3 MATERIALIZED t3 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; FirstMatch(t2); Using join buffer (incremental, BNL join) SELECT * FROM t1 WHERE t1.val IN (SELECT t2.val FROM t2 @@ -1260,8 +1257,8 @@ INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1); EXPLAIN SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index k k 10 NULL 4 Using where; Using index; Start temporary -1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY t2 ref k k 5 test.t1.i 1 Using where; Using index; Start temporary; End temporary SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); i 1 @@ -1637,7 +1634,7 @@ drop table t1,t2; # BUG#787299: Valgrind complains on a join query with two IN subqueries # create table t1 (a int); -insert into t1 values (1), (2), (3); +insert into t1 values (1), (2), (3),(1000),(2000); create table t2 as select * from t1; select * from t1 A, t1 B where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); @@ -1645,16 +1642,16 @@ a a 1 1 2 2 3 3 +1000 1000 +2000 2000 explain select * from t1 A, t1 B where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY A ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED C ALL NULL NULL NULL NULL 3 -3 MATERIALIZED D ALL NULL NULL NULL NULL 3 +1 PRIMARY A ALL NULL NULL NULL NULL 5 +1 PRIMARY C ALL NULL NULL NULL NULL 5 Using where; FirstMatch(A); Using join buffer (flat, BNL join) +1 PRIMARY B ALL NULL NULL NULL NULL 5 Using where; Using join buffer (incremental, BNL join) +1 PRIMARY D ALL NULL NULL NULL NULL 5 Using where; FirstMatch(B); Using join buffer (incremental, BNL join) drop table t1, t2; # # BUG#784441: Abort on semijoin with a view as the inner table @@ -1991,7 +1988,7 @@ f1 f3 f4 f2 f4 DROP TABLE t1,t2,t3; # # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90 -# (Original testcase) +# (Original, slightly modified testcase) # CREATE TABLE t1 (f1 int, f2 int ); INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL); @@ -2001,24 +1998,22 @@ CREATE TABLE t3 ( f1 int, f3 int ); INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0); CREATE TABLE t4 ( f2 int, KEY (f2) ); INSERT INTO t4 VALUES (0),(NULL); -CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ; +INSERT INTO t4 VALUES (0),(NULL),(-1),(-2),(-3); # The following must not have outer joins: explain extended -SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4 where f2 = 0 or f2 IS NULL); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t4 ref_or_null f2 f2 5 const 4 25.00 Using where; Using index; FirstMatch(t2) 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (incremental, BNL join) -2 MATERIALIZED t4 index f2 f2 5 NULL 2 100.00 Using index Warnings: -Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where `test`.`t3`.`f1` = `test`.`t1`.`f1` and `test`.`t1`.`f2` = `test`.`t2`.`f2` -SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); +Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where `test`.`t4`.`f2` = `test`.`t2`.`f3` and `test`.`t3`.`f1` = `test`.`t1`.`f1` and `test`.`t1`.`f2` = `test`.`t2`.`f2` and (`test`.`t2`.`f3` = 0 or `test`.`t2`.`f3` is null) +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4 where f2 = 0 or f2 IS NULL); f1 f2 f3 f3 2 0 0 0 4 0 0 0 4 0 0 0 -drop view v4; drop table t1, t2, t3, t4; # # BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90 @@ -2164,9 +2159,9 @@ INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5); explain SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 2 Using index; Using join buffer (flat, BNL join) -1 PRIMARY t3 ALL b NULL NULL NULL 5 Using where; Start temporary; End temporary; Using join buffer (incremental, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY t3 ref b b 5 test.t1.b 1 Using where; Start temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 Using index; End temporary SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3); b a 5 6 @@ -2189,10 +2184,10 @@ INSERT INTO t5 VALUES (7,0),(9,0); explain SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan -1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where -1 PRIMARY t4 ALL NULL NULL NULL NULL 3 FirstMatch(t5) -1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; Start temporary +1 PRIMARY t2 ref b b 5 test.t5.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using join buffer (incremental, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; End temporary; Using join buffer (incremental, BNL join) SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b); a 0 @@ -2271,10 +2266,10 @@ alias1.c IN (SELECT SQ3_alias1.b FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2) LIMIT 100; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 20 -1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) -1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (incremental, BNL join) -1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Start temporary; Using join buffer (incremental, BNL join) +1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 +1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) +1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Start temporary; Using join buffer (incremental, BNL join) +1 PRIMARY ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join) 1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary; Using join buffer (incremental, BNL join) 2 DERIVED t2 ALL NULL NULL NULL NULL 20 create table t3 as @@ -2447,9 +2442,9 @@ SET SESSION optimizer_switch='loosescan=off'; EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary -1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +1 PRIMARY t2 range idx idx 4 NULL 2 Using where; Using index +1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index; FirstMatch(t1) SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b); a 5 @@ -2457,9 +2452,9 @@ SET SESSION optimizer_switch='loosescan=on'; EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary -1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +1 PRIMARY t2 range idx idx 4 NULL 2 Using where; Using index +1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index; FirstMatch(t1) SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b); a 5 @@ -2510,10 +2505,9 @@ SELECT * FROM t1, t2 WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 system NULL NULL NULL NULL 1 -1 PRIMARY ALL distinct_key NULL NULL NULL 1 1 PRIMARY t1 ref a a 5 const 1 Using index 1 PRIMARY t2 ref a a 5 func 1 Using index -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 0 +1 PRIMARY t4 ALL NULL NULL NULL NULL 0 FirstMatch(t2); Using join buffer (flat, BNL join) SELECT * FROM t1, t2 WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4); a a @@ -2573,7 +2567,7 @@ INSERT INTO t1 VALUES (6,3),(7,1),(8,4),(9,3),(10,2); CREATE TABLE t2 ( c INT, d INT, KEY(c) ); INSERT INTO t2 VALUES -(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); +(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1),(11,11); analyze table t1,t2; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected @@ -2583,18 +2577,20 @@ test.t2 analyze status OK explain SELECT a, b, d FROM t1, t2 WHERE ( b, d ) IN -( SELECT b, d FROM t1, t2 WHERE b = c ); +( SELECT b, d FROM t1 as t3, t2 as t4 WHERE b = c ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 7 -1 PRIMARY t1 index b b 5 NULL 10 Using where; Using index; LooseScan -1 PRIMARY t2 ref c c 5 test.t1.b 1 Using where; FirstMatch(t1) -1 PRIMARY t1 ref b b 5 test.t1.b 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 PRIMARY t3 index b b 5 NULL 10 Using where; Using index; Start temporary +1 PRIMARY t4 ref c c 5 test.t3.b 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 PRIMARY t1 ALL b NULL NULL NULL 10 Using where; Using join buffer (incremental, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (incremental, BNL join) SELECT a, b, d FROM t1, t2 WHERE ( b, d ) IN -( SELECT b, d FROM t1, t2 WHERE b = c ); +( SELECT b, d FROM t1 as t3, t2 as t4 WHERE b = c ); a b d 1 2 1 1 2 1 +10 2 1 +10 2 1 2 1 2 2 1 2 3 3 3 @@ -2610,8 +2606,6 @@ a b d 8 4 2 9 3 3 9 3 3 -10 2 1 -10 2 1 DROP TABLE t1, t2; # Another testcase for the above that still uses LooseScan: create table t0(a int primary key); @@ -2780,21 +2774,21 @@ WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_1 ALL NULL NULL NULL NULL 11 Using where 1 PRIMARY t1_2 ALL NULL NULL NULL NULL 11 -1 PRIMARY ref key0 key0 5 test.t1_1.a 2 Using where; FirstMatch(t1_2) +1 PRIMARY ref key0 key0 5 test.t1_1.a 1 Using where; FirstMatch(t1_2) 3 DERIVED t1 ALL NULL NULL NULL NULL 11 SELECT * FROM t1 AS t1_1, t1 AS t1_2 WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 ); a b a b -3 1 9 1 -5 8 4 0 -3 9 9 1 2 4 4 0 2 4 6 8 2 6 4 0 2 6 6 8 +3 1 9 1 +3 9 9 1 5 4 4 0 +5 4 4 0 +5 8 4 0 7 7 7 7 -5 4 4 0 DROP VIEW v1; DROP TABLE t1; set @@join_cache_level= @tmp_jcl_978479; @@ -2938,9 +2932,9 @@ alias2.col_int_key = alias1.col_int_key WHERE alias1.pk = 58 OR alias1.col_varchar_key = 'o' ); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias1 index_merge PRIMARY,col_int_key,col_varchar_key PRIMARY,col_varchar_key 4,4 NULL 2 Using sort_union(PRIMARY,col_varchar_key); Using where; Start temporary -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -1 PRIMARY alias2 ALL col_int_key NULL NULL NULL 12 Range checked for each record (index map: 0x2); End temporary +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 +1 PRIMARY alias1 index_merge PRIMARY,col_int_key,col_varchar_key PRIMARY,col_varchar_key 4,4 NULL 2 Using sort_union(PRIMARY,col_varchar_key); Using where +1 PRIMARY alias2 ALL col_int_key NULL NULL NULL 12 Range checked for each record (index map: 0x2); FirstMatch(t2) SELECT * FROM t2 WHERE (field1) IN (SELECT alias1.col_varchar_nokey AS field1 @@ -3048,7 +3042,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00 Using temporary; Using filesort 1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 5 100.00 Start temporary 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary; Using join buffer (incremental, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 10.00 Using where; End temporary; Using join buffer (incremental, BNL join) Warnings: Note 1003 select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1` AS `c1`,'x' AS `c2` from `test`.`t1` semi join (`test`.`t1` left join `test`.`t3` on(`test`.`t1`.`c1` = `test`.`t3`.`c3`)) where `test`.`t1`.`pk` = `test`.`t1`.`pk` order by 'x',`test`.`t1`.`c1` DROP TABLE t1,t2,t3; @@ -3300,8 +3294,7 @@ explain extended SELECT Id FROM t1 WHERE Id in (SELECT t1_Id FROM t2 WHERE t2.col1 IS NULL); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ref col1 col1 5 const 2 100.00 Using index condition; Using where +1 PRIMARY t2 ref col1 col1 5 const 2 50.00 Using index condition; Using where; FirstMatch(t1) Warnings: Note 1003 select 1 AS `Id` from (`test`.`t2`) where `test`.`t2`.`t1_Id` = 1 and `test`.`t2`.`col1` is null DROP TABLE t1, t2; @@ -3482,20 +3475,21 @@ INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j'); CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) ); INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j'); INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m'); +insert into t1 select 'z','z' from seq_1_to_20; set @tmp_otimizer_switch= @@optimizer_switch; set @tmp_join_cache_level=@@join_cache_level; set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; set join_cache_level=0; EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON (c = b) -WHERE (a, b) IN (SELECT a, b FROM t1 t); +WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY t1 ALL idx_a NULL NULL NULL 23 +1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 1 Using where; Using index 1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index -2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +2 MATERIALIZED t ALL idx_a NULL NULL NULL 23 SELECT * FROM t1 LEFT JOIN t2 ON (c = b) -WHERE (a, b) IN (SELECT a, b FROM t1 t); +WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; a b c v v v v v v @@ -3503,14 +3497,14 @@ w w NULL t t NULL EXPLAIN SELECT * FROM t1 LEFT JOIN t3 ON (c = b) -WHERE (a, b) IN (SELECT a, b FROM t1 t); +WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY t1 ALL idx_a NULL NULL NULL 23 +1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 1 Using where 1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where -2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +2 MATERIALIZED t ALL idx_a NULL NULL NULL 23 SELECT * FROM t1 LEFT JOIN t3 ON (c = b) -WHERE (a, b) IN (SELECT a, b FROM t1 t); +WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; a b c d v v v v v v v v @@ -3519,14 +3513,14 @@ t t NULL NULL set join_cache_level=6; EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON (c = b) -WHERE (a, b) IN (SELECT a, b FROM t1 t); +WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY t1 ALL idx_a NULL NULL NULL 23 +1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 1 Using where; Using index 1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index -2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +2 MATERIALIZED t ALL idx_a NULL NULL NULL 23 SELECT * FROM t1 LEFT JOIN t2 ON (c = b) -WHERE (a, b) IN (SELECT a, b FROM t1 t); +WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; a b c v v v v v v @@ -3534,14 +3528,14 @@ w w NULL t t NULL EXPLAIN SELECT * FROM t1 LEFT JOIN t3 ON (c = b) -WHERE (a, b) IN (SELECT a, b FROM t1 t); +WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY t1 ALL idx_a NULL NULL NULL 23 +1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan 1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +2 MATERIALIZED t ALL idx_a NULL NULL NULL 23 SELECT * FROM t1 LEFT JOIN t3 ON (c = b) -WHERE (a, b) IN (SELECT a, b FROM t1 t); +WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; a b c d v v v v v v v v @@ -3568,9 +3562,8 @@ SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) GROUP BY a HAVING a != 'z'; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t range idx_a idx_a 4 NULL 3 Using where; Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index +1 PRIMARY t1 ref idx_a idx_a 4 test.t.a 1 Using index +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t) SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) GROUP BY a HAVING a != 'z'; a @@ -3582,9 +3575,8 @@ SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) GROUP BY a HAVING a != 'z'; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t range idx_a idx_a 4 NULL 3 Using where; Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index +1 PRIMARY t1 ref idx_a idx_a 4 test.t.a 1 Using index +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t) SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) GROUP BY a HAVING a != 'z'; a diff --git a/mysql-test/main/subselect_sj_jcl6.test b/mysql-test/main/subselect_sj_jcl6.test index f4f605c0406..e39a6887bde 100644 --- a/mysql-test/main/subselect_sj_jcl6.test +++ b/mysql-test/main/subselect_sj_jcl6.test @@ -3,6 +3,7 @@ # --source include/no_valgrind_without_big.inc --source include/default_optimizer_switch.inc +--source include/have_sequence.inc set @save_optimizer_switch_jcl6=@@optimizer_switch; set @@optimizer_switch='optimize_join_buffer_size=on'; @@ -132,6 +133,8 @@ CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) ); INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j'); INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m'); +insert into t1 select 'z','z' from seq_1_to_20; + set @tmp_otimizer_switch= @@optimizer_switch; set @tmp_join_cache_level=@@join_cache_level; set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; @@ -140,29 +143,29 @@ set join_cache_level=0; EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON (c = b) - WHERE (a, b) IN (SELECT a, b FROM t1 t); + WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; SELECT * FROM t1 LEFT JOIN t2 ON (c = b) - WHERE (a, b) IN (SELECT a, b FROM t1 t); + WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; EXPLAIN SELECT * FROM t1 LEFT JOIN t3 ON (c = b) - WHERE (a, b) IN (SELECT a, b FROM t1 t); + WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; SELECT * FROM t1 LEFT JOIN t3 ON (c = b) - WHERE (a, b) IN (SELECT a, b FROM t1 t); + WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; set join_cache_level=6; EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON (c = b) - WHERE (a, b) IN (SELECT a, b FROM t1 t); + WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; SELECT * FROM t1 LEFT JOIN t2 ON (c = b) - WHERE (a, b) IN (SELECT a, b FROM t1 t); + WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; EXPLAIN SELECT * FROM t1 LEFT JOIN t3 ON (c = b) - WHERE (a, b) IN (SELECT a, b FROM t1 t); + WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; SELECT * FROM t1 LEFT JOIN t3 ON (c = b) - WHERE (a, b) IN (SELECT a, b FROM t1 t); + WHERE (a, b) IN (SELECT a, b FROM t1 t) having t1.a !='z'; set optimizer_switch=@tmp_optimizer_switch; set join_cache_level=@tmp_join_cache_level; diff --git a/mysql-test/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result index 61a7ff25569..7bec603abef 100644 --- a/mysql-test/main/subselect_sj_mat.result +++ b/mysql-test/main/subselect_sj_mat.result @@ -107,11 +107,10 @@ a1 a2 explain extended select * from t1i where a1 in (select b1 from t2i where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1i range _it1_idx _it1_idx # NULL 3 100.00 Using where; -1 PRIMARY eq_ref distinct_key distinct_key # func 1 100.00 -2 MATERIALIZED t2i range it2i1,it2i3 it2i1 # NULL 5 100.00 Using where; +1 PRIMARY t2i index it2i1,it2i3 it2i1 # NULL 5 50.00 Using where; Using index; LooseScan +1 PRIMARY t1i ref _it1_idx _it1_idx # _ref_ 1 20.00 Warnings: -Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where `test`.`t2i`.`b1` > '0' +Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t2i`.`b1` > '0' select * from t1i where a1 in (select b1 from t2i where b1 > '0'); a1 a2 1 - 01 2 - 01 @@ -119,11 +118,11 @@ a1 a2 explain extended select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1i index it1i1,it1i3 # 18 # 3 100.00 # -1 PRIMARY eq_ref distinct_key # 8 # 1 100.00 # +1 PRIMARY ALL distinct_key # NULL # 5 100.00 # +1 PRIMARY t1i ref it1i1,it1i3 # 9 # 1 100.00 # 2 MATERIALIZED t2i range it2i1,it2i3 # 9 # 5 100.00 # Warnings: -Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from (/* select#2 */ select max(`test`.`t2i`.`b1`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where ``.`max(b1)` = `test`.`t1i`.`a1` +Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from (/* select#2 */ select max(`test`.`t2i`.`b1`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where `test`.`t1i`.`a1` = ``.`max(b1)` select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1); a1 a2 1 - 01 2 - 01 @@ -131,11 +130,10 @@ a1 a2 explain extended select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1i range _it1_idx _it1_idx # NULL 3 100.00 Using where; -1 PRIMARY eq_ref distinct_key distinct_key # func,func 1 100.00 -2 MATERIALIZED t2i range it2i1,it2i2,it2i3 it2i3 # NULL 5 100.00 Using where; +1 PRIMARY t2i index it2i1,it2i2,it2i3 it2i3 # NULL 5 50.00 Using where; Using index; LooseScan +1 PRIMARY t1i ref _it1_idx _it1_idx # _ref_ 1 20.00 Warnings: -Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where `test`.`t2i`.`b1` > '0' +Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t1i`.`a2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b1` > '0' select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0'); a1 a2 1 - 01 2 - 01 @@ -143,11 +141,11 @@ a1 a2 explain extended select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1i index it1i1,it1i2,it1i3 # # # 3 100.00 # -1 PRIMARY eq_ref distinct_key # # # 1 100.00 # +1 PRIMARY ALL distinct_key # # # 5 100.00 # +1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 # 2 MATERIALIZED t2i range it2i1,it2i3 # # # 5 100.00 # Warnings: -Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from (/* select#2 */ select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where ``.`b1` = `test`.`t1i`.`a1` and ``.`max(b2)` = `test`.`t1i`.`a2` +Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from (/* select#2 */ select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where `test`.`t1i`.`a1` = ``.`b1` and `test`.`t1i`.`a2` = ``.`max(b2)` select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1); a1 a2 1 - 01 2 - 01 @@ -155,11 +153,11 @@ a1 a2 explain extended select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1i index it1i1,it1i2,it1i3 # # # 3 100.00 # -1 PRIMARY eq_ref distinct_key # # # 1 100.00 # +1 PRIMARY ALL distinct_key # # # 5 100.00 # +1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 # 2 MATERIALIZED t2i range it2i1,it2i3 # # # 5 100.00 # Warnings: -Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from (/* select#2 */ select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where ``.`b1` = `test`.`t1i`.`a1` and ``.`min(b2)` = `test`.`t1i`.`a2` +Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from (/* select#2 */ select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where `test`.`t1i`.`a1` = ``.`b1` and `test`.`t1i`.`a2` = ``.`min(b2)` select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); a1 a2 1 - 01 2 - 01 @@ -279,7 +277,7 @@ explain extended select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 50.00 Using where; Using index; LooseScan -1 PRIMARY t1i ref it1i1,it1i2,it1i3 it1i3 18 test.t2i.b1,test.t2i.b2 1 100.00 Using index +1 PRIMARY t1i ref it1i1,it1i2,it1i3 it1i3 18 test.t2i.b1,test.t2i.b2 1 20.00 Using index Warnings: Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t1i`.`a2` = `test`.`t2i`.`b2` select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2); @@ -331,14 +329,12 @@ where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and (a1, a2) in (select c1, c2 from t3 where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where -3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where -3 MATERIALIZED t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t3.c1,test.t3.c2 1 100.00 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t1.a1,test.t1.a2 1 100.00 Using index; Start temporary +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 20.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 4 15.00 Using where; End temporary; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t3`.`c1` and `test`.`t2i`.`b2` = `test`.`t3`.`c2` and `test`.`t2`.`b1` > '0' and `test`.`t3`.`c2` > '0' +Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t1`.`a1` and `test`.`t2`.`b1` = `test`.`t1`.`a1` and `test`.`t3`.`c1` = `test`.`t1`.`a1` and `test`.`t2i`.`b2` = `test`.`t1`.`a2` and `test`.`t2`.`b2` = `test`.`t1`.`a2` and `test`.`t3`.`c2` = `test`.`t1`.`a2` and `test`.`t1`.`a1` > '0' and `test`.`t1`.`a2` > '0' select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and (a1, a2) in (select c1, c2 from t3 @@ -352,14 +348,12 @@ where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and (a1, a2) in (select c1, c2 from t3i where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1i range it1i1,it1i2,it1i3 # # # 3 100.00 # -1 PRIMARY eq_ref distinct_key # # # 1 100.00 # -1 PRIMARY eq_ref distinct_key # # # 1 100.00 # -2 MATERIALIZED t2i range it2i1,it2i2,it2i3 # # # 5 100.00 # -3 MATERIALIZED t3i range it3i1,it3i2,it3i3 # # # 4 100.00 # -3 MATERIALIZED t2i ref it2i1,it2i2,it2i3 # # # 1 100.00 # +1 PRIMARY t2i index it2i1,it2i2,it2i3 # # # 5 50.00 # +1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 20.00 # +1 PRIMARY t3i ref it3i1,it3i2,it3i3 # # # 1 100.00 # +1 PRIMARY t2i ref it2i1,it2i2,it2i3 # # # 1 60.00 # Warnings: -Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where `test`.`t2i`.`b1` = `test`.`t3i`.`c1` and `test`.`t2i`.`b2` = `test`.`t3i`.`c2` and `test`.`t2i`.`b1` > '0' and `test`.`t3i`.`c2` > '0' +Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t3i`.`c1` = `test`.`t2i`.`b1` and `test`.`t2i`.`b1` = `test`.`t2i`.`b1` and `test`.`t1i`.`a2` = `test`.`t2i`.`b2` and `test`.`t3i`.`c2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b1` > '0' and `test`.`t2i`.`b2` > '0' select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and (a1, a2) in (select c1, c2 from t3i @@ -375,16 +369,14 @@ b2 in (select c2 from t3 where c2 LIKE '%03')) and (a1, a2) in (select c1, c2 from t3 where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where -5 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where -5 MATERIALIZED t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t3.c1,test.t3.c2 1 100.00 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t1.a1,test.t1.a2 1 100.00 Using index; Start temporary +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 20.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 4 15.00 Using where; End temporary; Using join buffer (flat, BNL join) 4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t3`.`c1` and `test`.`t2i`.`b2` = `test`.`t3`.`c2` and (<`test`.`t2`.`b2`>((`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( (/* select#3 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%02' ), (`test`.`t2`.`b2` in on distinct_key where `test`.`t2`.`b2` = ``.`c2`)))) or <`test`.`t2`.`b2`>((`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( (/* select#4 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%03' ), (`test`.`t2`.`b2` in on distinct_key where `test`.`t2`.`b2` = ``.`c2`))))) and `test`.`t3`.`c2` > '0' +Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t1`.`a1` and `test`.`t2`.`b1` = `test`.`t1`.`a1` and `test`.`t3`.`c1` = `test`.`t1`.`a1` and `test`.`t2i`.`b2` = `test`.`t1`.`a2` and `test`.`t2`.`b2` = `test`.`t1`.`a2` and `test`.`t3`.`c2` = `test`.`t1`.`a2` and (<`test`.`t2`.`b2`>((`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( (/* select#3 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%02' ), (`test`.`t2`.`b2` in on distinct_key where `test`.`t2`.`b2` = ``.`c2`)))) or <`test`.`t2`.`b2`>((`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( (/* select#4 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%03' ), (`test`.`t2`.`b2` in on distinct_key where `test`.`t2`.`b2` = ``.`c2`))))) and `test`.`t1`.`a2` > '0' select * from t1 where (a1, a2) in (select b1, b2 from t2 where b2 in (select c2 from t3 where c2 LIKE '%02') or @@ -402,7 +394,7 @@ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 20.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) 1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 5 MATERIALIZED t3c ALL NULL NULL NULL NULL 4 100.00 Using where 5 MATERIALIZED t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t3c.c1,test.t3c.c2 1 100.00 Using index @@ -435,22 +427,18 @@ where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL # # # 3 100.00 # -1 PRIMARY eq_ref distinct_key # # # 1 100.00 # -1 PRIMARY eq_ref distinct_key # # # 1 100.00 # -2 MATERIALIZED t2 ALL NULL # # # 5 100.00 # -5 MATERIALIZED t3 ALL NULL # # # 4 100.00 # -5 MATERIALIZED t2i ref it2i1,it2i2,it2i3 # # # 1 100.00 # +1 PRIMARY t2i ref it2i1,it2i2,it2i3 # # # 1 100.00 # +1 PRIMARY t2 ALL NULL # # # 5 20.00 # +1 PRIMARY t3 ALL NULL # # # 4 15.00 # 4 MATERIALIZED t3 ALL NULL # # # 4 100.00 # 3 MATERIALIZED t3 ALL NULL # # # 4 100.00 # -7 UNION t1i range it1i1,it1i2,it1i3 # # # 3 100.00 # -7 UNION eq_ref distinct_key # # # 1 100.00 # -7 UNION eq_ref distinct_key # # # 1 100.00 # -8 MATERIALIZED t2i range it2i1,it2i2,it2i3 # # # 5 100.00 # -9 MATERIALIZED t3i range it3i1,it3i2,it3i3 # # # 4 100.00 # -9 MATERIALIZED t2i ref it2i1,it2i2,it2i3 # # # 1 100.00 # +7 UNION t2i index it2i1,it2i2,it2i3 # # # 5 50.00 # +7 UNION t1i ref it1i1,it1i2,it1i3 # # # 1 20.00 # +7 UNION t3i ref it3i1,it3i2,it3i3 # # # 1 100.00 # +7 UNION t2i ref it2i1,it2i2,it2i3 # # # 1 60.00 # NULL UNION RESULT ALL NULL # # # NULL NULL # Warnings: -Note 1003 (/* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t3`.`c1` and `test`.`t2i`.`b2` = `test`.`t3`.`c2` and (<`test`.`t2`.`b2`>((`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( (/* select#3 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%02' ), (`test`.`t2`.`b2` in on distinct_key where `test`.`t2`.`b2` = ``.`c2`)))) or <`test`.`t2`.`b2`>((`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( (/* select#4 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%03' ), (`test`.`t2`.`b2` in on distinct_key where `test`.`t2`.`b2` = ``.`c2`))))) and `test`.`t3`.`c2` > '0') union (/* select#7 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where `test`.`t2i`.`b1` = `test`.`t3i`.`c1` and `test`.`t2i`.`b2` = `test`.`t3i`.`c2` and `test`.`t2i`.`b1` > '0' and `test`.`t3i`.`c2` > '0') +Note 1003 (/* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t1`.`a1` and `test`.`t2`.`b1` = `test`.`t1`.`a1` and `test`.`t3`.`c1` = `test`.`t1`.`a1` and `test`.`t2i`.`b2` = `test`.`t1`.`a2` and `test`.`t2`.`b2` = `test`.`t1`.`a2` and `test`.`t3`.`c2` = `test`.`t1`.`a2` and (<`test`.`t2`.`b2`>((`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( (/* select#3 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%02' ), (`test`.`t2`.`b2` in on distinct_key where `test`.`t2`.`b2` = ``.`c2`)))) or <`test`.`t2`.`b2`>((`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( (/* select#4 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%03' ), (`test`.`t2`.`b2` in on distinct_key where `test`.`t2`.`b2` = ``.`c2`))))) and `test`.`t1`.`a2` > '0') union (/* select#7 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t3i`.`c1` = `test`.`t2i`.`b1` and `test`.`t2i`.`b1` = `test`.`t2i`.`b1` and `test`.`t1i`.`a2` = `test`.`t2i`.`b2` and `test`.`t3i`.`c2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b1` > '0' and `test`.`t2i`.`b2` > '0') (select * from t1 where (a1, a2) in (select b1, b2 from t2 where b2 in (select c2 from t3 where c2 LIKE '%02') or @@ -542,9 +530,9 @@ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and where (c1, c2) in (select b1, b2 from t2i where b2 > '0' or b2 = a2)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 20.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) 1 PRIMARY t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t1.a1,test.t1.a2 1 100.00 Using index; Start temporary -1 PRIMARY t3c ALL NULL NULL NULL NULL 4 100.00 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t3c ALL NULL NULL NULL NULL 4 15.00 Using where; End temporary; Using join buffer (flat, BNL join) 4 MATERIALIZED t3b ALL NULL NULL NULL NULL 4 100.00 Using where 3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where Warnings: @@ -658,7 +646,7 @@ from t1_16 where a1 in (select b1 from t2_16 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where `test`.`t2_16`.`b1` = `test`.`t1_16`.`a1` and `test`.`t1_16`.`a1` > '0' select left(a1,7), left(a2,7) @@ -672,7 +660,7 @@ from t1_16 where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where `test`.`t2_16`.`b1` = `test`.`t1_16`.`a1` and `test`.`t2_16`.`b2` = `test`.`t1_16`.`a2` and `test`.`t1_16`.`a1` > '0' select left(a1,7), left(a2,7) @@ -739,7 +727,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; Using join buffer (flat, BNL join) 1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) -1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 0.56 Using where; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2_16` join `test`.`t2` join `test`.`t1_16`) where `test`.`t2`.`b1` = `test`.`t3`.`c1` and `test`.`t2_16`.`b1` = `test`.`t1_16`.`a1` and `test`.`t2_16`.`b2` = `test`.`t1_16`.`a2` and `test`.`t2`.`b2` = substr(`test`.`t1_16`.`a2`,1,6) and `test`.`t3`.`c2` > '0' and concat(`test`.`t1`.`a1`,'x') = left(`test`.`t1_16`.`a1`,8) drop table t1_16, t2_16, t3_16; @@ -773,7 +761,7 @@ from t1_512 where a1 in (select b1 from t2_512 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where `test`.`t2_512`.`b1` = `test`.`t1_512`.`a1` and `test`.`t1_512`.`a1` > '0' select left(a1,7), left(a2,7) @@ -787,7 +775,7 @@ from t1_512 where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where `test`.`t2_512`.`b1` = `test`.`t1_512`.`a1` and `test`.`t2_512`.`b2` = `test`.`t1_512`.`a2` and `test`.`t1_512`.`a1` > '0' select left(a1,7), left(a2,7) @@ -877,7 +865,7 @@ from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where `test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1` and `test`.`t1_1024`.`a1` > '0' select left(a1,7), left(a2,7) @@ -891,7 +879,7 @@ from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where `test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1` and `test`.`t2_1024`.`b2` = `test`.`t1_1024`.`a2` and `test`.`t1_1024`.`a1` > '0' select left(a1,7), left(a2,7) @@ -905,7 +893,7 @@ from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where `test`.`t2_1024`.`b1` > '0' and `test`.`t1_1024`.`a1` = substr(`test`.`t2_1024`.`b1`,1,1024) select left(a1,7), left(a2,7) @@ -980,7 +968,7 @@ from t1_1025 where a1 in (select b1 from t2_1025 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where `test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1` and `test`.`t1_1025`.`a1` > '0' select left(a1,7), left(a2,7) @@ -994,7 +982,7 @@ from t1_1025 where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where `test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1` and `test`.`t2_1025`.`b2` = `test`.`t1_1025`.`a2` and `test`.`t1_1025`.`a1` > '0' select left(a1,7), left(a2,7) @@ -1008,7 +996,7 @@ from t1_1025 where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where `test`.`t2_1025`.`b1` > '0' and `test`.`t1_1025`.`a1` = substr(`test`.`t2_1025`.`b1`,1,1025) select left(a1,7), left(a2,7) @@ -1090,7 +1078,7 @@ from t1bb where (a1, a2) in (select b1, b2 from t2bb); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1bb ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2bb ALL NULL NULL NULL NULL 3 33.33 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) Warnings: Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` semi join (`test`.`t2bb`) where `test`.`t2bb`.`b1` = `test`.`t1bb`.`a1` and `test`.`t2bb`.`b2` = `test`.`t1bb`.`a2` select bin(a1), a2 @@ -1152,11 +1140,10 @@ create index it1a on t1(a); explain extended select a from t1 where a in (select c from t2 where d >= 20); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 index it1a it1a 4 NULL 7 100.00 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Using where; Start temporary +1 PRIMARY t1 ref it1a it1a 4 test.t2.c 1 16.67 Using index; End temporary Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`d` >= 20 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t2`.`c` and `test`.`t2`.`d` >= 20 select a from t1 where a in (select c from t2 where d >= 20); a 2 @@ -1167,11 +1154,10 @@ insert into t2 values (1,10); explain extended select a from t1 where a in (select c from t2 where d >= 20); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 index it1a it1a 4 NULL 7 100.00 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 7 100.00 Using where; Start temporary +1 PRIMARY t1 ref it1a it1a 4 test.t2.c 1 14.29 Using index; End temporary Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`d` >= 20 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t2`.`c` and `test`.`t2`.`d` >= 20 select a from t1 where a in (select c from t2 where d >= 20); a 2 @@ -1181,7 +1167,7 @@ a explain extended select a from t1 group by a having a in (select c from t2 where d >= 20); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 range NULL it1a 4 NULL 8 100.00 Using index for group-by +1 PRIMARY t1 range NULL it1a 4 NULL 7 100.00 Using index for group-by 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`c`)))) @@ -1193,7 +1179,7 @@ create index iab on t1(a, b); explain extended select a from t1 group by a having a in (select c from t2 where d >= 20); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 range NULL it1a 4 NULL 8 100.00 Using index for group-by +1 PRIMARY t1 range NULL it1a 4 NULL 7 100.00 Using index for group-by 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`c`)))) @@ -1205,7 +1191,7 @@ explain extended select a from t1 group by a having a in (select c from t2 where d >= some(select e from t3 where max(b)=e)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 range NULL iab 4 NULL 8 100.00 Using index for group-by +1 PRIMARY t1 range NULL iab 4 NULL 7 100.00 Using index for group-by 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where 3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where Warnings: @@ -1222,7 +1208,7 @@ select a from t1 where a in (select c from t2 where d >= some(select e from t3 where b=e)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 7 100.00 Start temporary -1 PRIMARY t1 ref it1a,iab iab 4 test.t2.c 1 100.00 Using where; Using index; End temporary +1 PRIMARY t1 ref it1a,iab iab 4 test.t2.c 1 9.41 Using where; Using index; End temporary 3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where Warnings: Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1 @@ -1549,13 +1535,15 @@ SET @@optimizer_switch='semijoin=on,materialization=on'; EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 7 func,func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2); COUNT(*) 2 set @@optimizer_switch= @local_optimizer_switch; DROP TABLE t1, t2; +# +# BUG#46548 IN-subqueries return 0 rows with materialization=on +# CREATE TABLE t1 ( pk int, a varchar(1), @@ -1565,16 +1553,19 @@ d varchar(4), PRIMARY KEY (pk) ); INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff'); +insert into t1 select seq,'x','xxxx','xxxx','xxxx' from seq_10_to_40; CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); +insert into t2 select -seq,'a','aaaa','aaaa','aaaa' from seq_1_to_20; +insert into t2 select seq,'b','bbbb','bbbb','bbbb' from seq_100_to_200; set @local_optimizer_switch=@@optimizer_switch; set @@optimizer_switch=@optimizer_switch_local_default; SET @@optimizer_switch='semijoin=on,materialization=on'; EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 33 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan +2 MATERIALIZED t2 ALL PRIMARY NULL NULL NULL 123 Using where SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); pk 2 @@ -1893,7 +1884,7 @@ SELECT * FROM t1 WHERE a IN ( SELECT MIN(a) FROM t1 ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system a NULL NULL NULL 1 100.00 -1 PRIMARY system NULL NULL NULL NULL 1 100.00 +1 PRIMARY system NULL NULL NULL NULL 0 0.00 2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away Warnings: Note 1003 /* select#1 */ select 8 AS `a` from dual where 1 @@ -1935,12 +1926,13 @@ DROP TABLE t1,t2; # create table t1 (a int, b int); insert into t1 values (7,5), (3,3), (5,4), (9,3); +insert into t1 select seq,seq from seq_100_to_200; create table t2 (a int, b int, index i_a(a)); insert into t2 values (4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1); explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +1 PRIMARY t1 ALL NULL NULL NULL NULL 105 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); @@ -1993,11 +1985,11 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 Using where 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = ``.`MAX(c)` and ((/*always not null*/ 1 is null) or ``.`MAX(c)` = 7) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and ``.`MAX(c)` = `test`.`t1`.`a` and (`test`.`t1`.`a` is null or `test`.`t1`.`a` = 7) SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); a b @@ -2006,8 +1998,8 @@ EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY const distinct_key distinct_key 4 const 1 -1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY const distinct_key distinct_key 4 const 1 Using where 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); @@ -2031,10 +2023,9 @@ WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 -1 PRIMARY t2 index c c 5 NULL 8 Using index -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -2 MATERIALIZED s2 ref d d 4 const 2 Using where; Using index -2 MATERIALIZED s1 ALL c NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +1 PRIMARY t2 index c c 5 NULL 8 Using where; Using index +1 PRIMARY s1 ref c c 5 test.t2.c 1 Using where +1 PRIMARY s2 ref d d 4 const 2 Using where; Using index; FirstMatch(t2) 3 SUBQUERY t2 ALL NULL NULL NULL NULL 8 SELECT a, c FROM t1, t2 WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 @@ -2051,10 +2042,9 @@ WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 -1 PRIMARY t2 index c c 5 NULL 8 Using index -1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 -2 MATERIALIZED s2 ref d d 4 const 2 Using where; Using index -2 MATERIALIZED s1 hash_ALL c #hash#$hj 5 const 8 Using where; Using join buffer (flat, BNLH join) +1 PRIMARY t2 index c c 5 NULL 8 Using where; Using index +1 PRIMARY s1 hash_ALL c #hash#c 5 test.t2.c 8 Using where; Using join buffer (flat, BNLH join) +1 PRIMARY s2 hash_range d #hash#d:d 4:4 const 2 Using where; Using index; FirstMatch(t2); Using join buffer (incremental, BNLH join) 3 SUBQUERY t2 ALL NULL NULL NULL NULL 8 SELECT a, c FROM t1, t2 WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 @@ -2236,9 +2226,8 @@ mysqltest1 EXPLAIN EXTENDED SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 100.00 Using temporary; Using filesort -1 PRIMARY t1 eq_ref db db 764 information_schema.schemata.SCHEMA_NAME 1 100.00 Using where; Using index -2 MATERIALIZED schemata ALL NULL NULL NULL NULL NULL NULL +1 PRIMARY t1 index db db 764 NULL 4 100.00 Using index; Using temporary; Using filesort +1 PRIMARY schemata ALL NULL NULL NULL NULL NULL NULL Using where; FirstMatch(t1); Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t1`.`db` AS `db` from `test`.`t1` semi join (`information_schema`.`schemata`) where `test`.`t1`.`db` = `information_schema`.`schemata`.`SCHEMA_NAME` order by `test`.`t1`.`db` desc drop table t1; @@ -2270,8 +2259,10 @@ drop table t1; CREATE TABLE t1 ( pk INT, f1 INT NOT NULL, f2 VARCHAR(3), f3 INT NULL, PRIMARY KEY(pk)) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,1,'foo',8), (2,5,'bar',7); +create table t2 like t1; +insert into t2 select * from t1; SELECT sq1.f2 FROM t1 AS sq1 -WHERE EXISTS ( SELECT * FROM t1 AS sq2 +WHERE EXISTS ( SELECT * FROM t2 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); f2 foo @@ -2283,18 +2274,17 @@ WHERE EXISTS ( SELECT * FROM t1 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY sq1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where; FirstMatch 2 DEPENDENT SUBQUERY sq2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 # this checks the result set above set optimizer_switch= 'materialization=off,semijoin=off'; SELECT sq1.f2 FROM t1 AS sq1 -WHERE EXISTS ( SELECT * FROM t1 AS sq2 +WHERE EXISTS ( SELECT * FROM t2 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); f2 foo set optimizer_switch= @local_optimizer_switch; -DROP TABLE t1; +DROP TABLE t1,t2; # # MDEV-12145: IN subquery used in WHERE of EXISTS subquery # @@ -2317,10 +2307,9 @@ WHERE EXISTS ( SELECT * FROM t2, t3 WHERE i3 = i2 AND f1 IN ( SELECT f3 FROM t3 ) ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 8 12.50 Using where; FirstMatch 2 DEPENDENT SUBQUERY t2 range i2 i2 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY t3 ref i3 i3 5 test.t2.i2 2 100.00 Using index -3 MATERIALIZED t3 ALL NULL NULL NULL NULL 8 100.00 +2 DEPENDENT SUBQUERY t3 ref i3 i3 5 test.t2.i2 1 100.00 Using index Warnings: Note 1276 Field or reference 'test.t1.f1' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where <`test`.`t1`.`f1`>(exists(/* select#2 */ select 1 from `test`.`t2` semi join (`test`.`t3`) join `test`.`t3` where `test`.`t3`.`i3` = `test`.`t2`.`i2` and `test`.`t1`.`f1` = `test`.`t3`.`f3` limit 1)) @@ -2356,9 +2345,8 @@ SELECT pk, f1, ( SELECT COUNT(*) FROM t2 WHERE t1.pk IN ( SELECT f2 FROM t2 ) ) AS sq FROM t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00 -2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 20.00 Using where; FirstMatch 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using join buffer (flat, BNL join) -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Warnings: Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`f1` AS `f1`,<`test`.`t1`.`pk`>((/* select#2 */ select count(0) from `test`.`t2` semi join (`test`.`t2`) where `test`.`t1`.`pk` = `test`.`t2`.`f2`)) AS `sq` from `test`.`t1` @@ -2441,11 +2429,10 @@ WHERE t2.ugroup = t3_i.sys_id AND t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND t2.user = '86826bf03710200044e0bfc8bcbe5d79'); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where +1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary +1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where +1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index -2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where -2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where set statement optimizer_prune_level=1 for explain SELECT t1.assignment_group FROM t1, t3 WHERE t1.assignment_group = t3.sys_id AND @@ -2456,11 +2443,10 @@ WHERE t2.ugroup = t3_i.sys_id AND t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND t2.user = '86826bf03710200044e0bfc8bcbe5d79'); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where +1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary +1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where +1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index -3 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where -3 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where SELECT t1.assignment_group FROM t1, t3 WHERE t1.assignment_group = t3.sys_id AND @@ -2492,8 +2478,7 @@ explain SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); 1 1 @@ -2505,8 +2490,7 @@ explain SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index id id 4 NULL 9 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); 1 1 @@ -2555,20 +2539,17 @@ drop procedure prepare_data; set @@optimizer_switch= @local_optimizer_switch; drop table t1,t2,t3; CREATE TABLE t1 ( id int NOT NULL, key(id)); -INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +INSERT INTO t1 select seq from seq_11_to_39; CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); -INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +INSERT INTO t2 select seq,seq+1 from seq_11_to_50; CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index id id 4 NULL 9 Using index +1 PRIMARY t1 index id id 4 NULL 29 Using index 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 40 Using where SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); 1 -1 -1 -1 drop table t1,t2; drop view v1; # diff --git a/mysql-test/main/subselect_sj_mat.test b/mysql-test/main/subselect_sj_mat.test index 6a9c78adc52..4302fc10c81 100644 --- a/mysql-test/main/subselect_sj_mat.test +++ b/mysql-test/main/subselect_sj_mat.test @@ -4,6 +4,7 @@ # --source include/default_optimizer_switch.inc +--source include/have_sequence.inc set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on'); set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; @@ -1174,9 +1175,9 @@ set @@optimizer_switch= @local_optimizer_switch; DROP TABLE t1, t2; -# -# BUG#46548 IN-subqueries return 0 rows with materialization=on -# +--echo # +--echo # BUG#46548 IN-subqueries return 0 rows with materialization=on +--echo # CREATE TABLE t1 ( pk int, a varchar(1), @@ -1186,9 +1187,12 @@ CREATE TABLE t1 ( PRIMARY KEY (pk) ); INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff'); +insert into t1 select seq,'x','xxxx','xxxx','xxxx' from seq_10_to_40; CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); +insert into t2 select -seq,'a','aaaa','aaaa','aaaa' from seq_1_to_20; +insert into t2 select seq,'b','bbbb','bbbb','bbbb' from seq_100_to_200; set @local_optimizer_switch=@@optimizer_switch; set @@optimizer_switch=@optimizer_switch_local_default; @@ -1553,6 +1557,7 @@ DROP TABLE t1,t2; --echo # create table t1 (a int, b int); insert into t1 values (7,5), (3,3), (5,4), (9,3); +insert into t1 select seq,seq from seq_100_to_200; create table t2 (a int, b int, index i_a(a)); @@ -1883,9 +1888,11 @@ drop table t1; CREATE TABLE t1 ( pk INT, f1 INT NOT NULL, f2 VARCHAR(3), f3 INT NULL, PRIMARY KEY(pk)) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,1,'foo',8), (2,5,'bar',7); +create table t2 like t1; +insert into t2 select * from t1; SELECT sq1.f2 FROM t1 AS sq1 - WHERE EXISTS ( SELECT * FROM t1 AS sq2 + WHERE EXISTS ( SELECT * FROM t2 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); set @local_optimizer_switch= @@optimizer_switch; @@ -1899,12 +1906,12 @@ SELECT sq1.f2 FROM t1 AS sq1 --echo # this checks the result set above set optimizer_switch= 'materialization=off,semijoin=off'; SELECT sq1.f2 FROM t1 AS sq1 - WHERE EXISTS ( SELECT * FROM t1 AS sq2 + WHERE EXISTS ( SELECT * FROM t2 AS sq2 WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 ); set optimizer_switch= @local_optimizer_switch; -DROP TABLE t1; +DROP TABLE t1,t2; --echo # --echo # MDEV-12145: IN subquery used in WHERE of EXISTS subquery @@ -2248,9 +2255,9 @@ set @@optimizer_switch= @local_optimizer_switch; drop table t1,t2,t3; CREATE TABLE t1 ( id int NOT NULL, key(id)); -INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +INSERT INTO t1 select seq from seq_11_to_39; CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); -INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +INSERT INTO t2 select seq,seq+1 from seq_11_to_50; CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); diff --git a/mysql-test/main/subselect_sj_nonmerged.result b/mysql-test/main/subselect_sj_nonmerged.result index a3e6c493930..2413ce3a557 100644 --- a/mysql-test/main/subselect_sj_nonmerged.result +++ b/mysql-test/main/subselect_sj_nonmerged.result @@ -47,8 +47,8 @@ id select_type table type possible_keys key key_len ref rows Extra # Compare to this which really will have 50 record combinations: explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b, t1.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 index PRIMARY PRIMARY 8 NULL 100 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 test.t3.a 1 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 50 +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 .max(t2.a) 1 Using where; Using index 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) SET @save_optimizer_switch=@@optimizer_switch; @@ -57,8 +57,8 @@ SET optimizer_switch='outer_join_with_cache=off'; explain select * from t3 where a in (select max(t2.a) from t1 left join t2 on t1.a=t2.a group by t2.b, t1.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 index PRIMARY PRIMARY 8 NULL 100 Using index -1 PRIMARY eq_ref distinct_key distinct_key 4 test.t3.a 1 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 50 +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 .max(t2.a) 1 Using where; Using index 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using temporary 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using where SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/main/table_elim.result b/mysql-test/main/table_elim.result index 4da85c4a9ca..580b1cf5a0d 100644 --- a/mysql-test/main/table_elim.result +++ b/mysql-test/main/table_elim.result @@ -563,9 +563,9 @@ JOIN t5 ON t4.f3 ON t3.f1 = t5.f5 ON t2.f4 = t3.f4 WHERE t3.f2 ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where -1 SIMPLE t5 ref f5 f5 5 test.t3.f1 2 Using where; Using index +1 SIMPLE t5 ref f5 f5 5 test.t3.f1 1 Using where; Using index 1 SIMPLE t4 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t2 ALL f4 NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ref f4 f4 1003 test.t3.f4 1 Using where # ^^ The above must not produce a QEP of t3,t5,t2,t4 # as that violates the "no interleaving of outer join nests" rule. DROP TABLE t1,t2,t3,t4,t5; @@ -737,13 +737,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -769,13 +772,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -788,12 +794,15 @@ EXPLAIN "key_length": "8", "used_key_parts": ["b"], "ref": ["test.t1.a"], + "loops": 10, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "trigcond(t1.a = v2b.b and trigcond(t1.a is not null))", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "const_condition": "1", "filesort": { "sort_key": "t11.a", @@ -803,7 +812,9 @@ EXPLAIN "table": { "table_name": "t11", "access_type": "ALL", + "loops": 1, "rows": 1000, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -831,13 +842,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -857,13 +871,16 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "const_condition": "1", "nested_loop": [ { "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -876,12 +893,15 @@ EXPLAIN "key_length": "5", "used_key_parts": ["b"], "ref": ["test.t1.a"], + "loops": 10, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "trigcond(trigcond(t1.a is not null))", "materialized": { "query_block": { "select_id": 2, + "cost": "COST_REPLACED", "const_condition": "1", "filesort": { "sort_key": "t11.a", @@ -891,7 +911,9 @@ EXPLAIN "table": { "table_name": "t11", "access_type": "ALL", + "loops": 1, "rows": 1000, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -904,7 +926,9 @@ EXPLAIN "key_length": "4", "used_key_parts": ["pk"], "ref": ["test.t11.b"], + "loops": 1000, "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "trigcond(trigcond(t11.b is not null))" } @@ -946,7 +970,7 @@ group by yyy; explain select t1.* from t1 left join v2e on v2e.yyy=t1.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 10 -1 PRIMARY ref key0 key0 5 test.t1.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t1.a 1 Using where 2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table create table t2 (a int, b int, c int); insert into t2 select A.seq, B.seq, 123 from seq_1_to_3 A, seq_1_to_3 B; @@ -956,14 +980,14 @@ explain select t1.* from t1 left join (select a, count(*) as cnt from t2 group by a, b) D on D.a=t1.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 10 -1 PRIMARY ref key0 key0 5 test.t1.a 2 Using where +1 PRIMARY ref key0 key0 5 test.t1.a 1 Using where 2 DERIVED t2 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort # Still no elimination 'cause field D.b is just an alias for t2.a explain select t1.* from t1 left join (select a, a as b, count(*) as cnt from t2 group by a, b) D on D.a=t1.a and D.b=t1.b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 10 -1 PRIMARY ref key0 key0 10 test.t1.a,test.t1.b 2 Using where +1 PRIMARY ref key0 key0 10 test.t1.a,test.t1.b 1 Using where 2 DERIVED t2 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort Warnings: Warning 1052 Column 'b' in group statement is ambiguous diff --git a/mysql-test/main/table_elim.test b/mysql-test/main/table_elim.test index d6bf925c2c0..26c56630784 100644 --- a/mysql-test/main/table_elim.test +++ b/mysql-test/main/table_elim.test @@ -680,6 +680,7 @@ group by t11.a; explain select t1.* from t1 left join v2b on v2b.a=t1.a; --echo # Check format JSON as well +--source include/explain-no-costs.inc explain format=JSON select t1.* from t1 left join v2b on t1.a=v2b.a; --echo # Elimination of a whole subquery @@ -692,6 +693,7 @@ explain select t1.* from t1 left join explain select t1.* from t1 left join v2b on t1.a=v2b.b; --echo # Check format JSON as well +--source include/explain-no-costs.inc explain format=JSON select t1.* from t1 left join v2b on t1.a=v2b.b; create view v2c as @@ -703,12 +705,14 @@ group by t11.a; explain select t1.* from t1 left join v2c on v2c.a=t1.a; --echo # Check format JSON as well +--source include/explain-no-costs.inc explain format=JSON select t1.* from t1 left join v2c on v2c.a=t1.a; --echo # In this case v2c cannot be eliminated (since v2c.b is not unique)! explain select t1.* from t1 left join v2c on t1.a=v2c.b; --echo # Check format JSON as well +--source include/explain-no-costs.inc explain format=JSON select t1.* from t1 left join v2c on t1.a=v2c.b; --echo # Create a view with multiple fields in the GROUP BY clause: diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result index e6d973d53ee..86479c843c2 100644 --- a/mysql-test/main/table_value_constr.result +++ b/mysql-test/main/table_value_constr.result @@ -567,12 +567,12 @@ where t1.a=t2.a and st<3 select * from t2; a b st 1 1 1 -1 2 2 1 1 2 -1 2 3 -1 2 3 1 1 3 1 1 3 +1 2 2 +1 2 3 +1 2 3 # recursive CTE that uses VALUES structure(s) : computation of factorial (first 10 elements) with recursive fact(n,f) as ( @@ -743,21 +743,19 @@ a b explain extended select * from t1 where a in (values (1)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` explain extended select * from t1 where a in (select * from (values (1)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` # IN-subquery with VALUES structure(s) : UNION with VALUES on the first place select * from t1 where a in (values (1) union select 2); @@ -776,7 +774,7 @@ explain extended select * from t1 where a in (values (1) union select 2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -4 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +4 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL @@ -787,7 +785,7 @@ where a in (select * from (values (1)) as tvc_0 union select 2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL @@ -812,7 +810,7 @@ where a in (select 2 union values (1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -4 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +4 DEPENDENT UNION eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -823,7 +821,7 @@ select * from (values (1)) tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -3 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +3 DEPENDENT UNION ref key0 key0 4 func 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -848,7 +846,7 @@ explain extended select * from t1 where a in (values (1) union all select b from t1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -4 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +4 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 6 100.00 Using where Warnings: @@ -858,7 +856,7 @@ where a in (select * from (values (1)) as tvc_0 union all select b from t1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 4 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 6 100.00 Using where Warnings: @@ -880,18 +878,18 @@ explain extended select * from t1 where a not in (values (1),(2)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +3 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 4 func 1 100.00 Using where; Full scan on NULL key 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#3 */ select `tvc_0`.`1` from (values (1),(2)) `tvc_0` ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`1`)))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<`test`.`t1`.`a`>((`test`.`t1`.`a`,(((`test`.`t1`.`a`) in on distinct_key where trigcond((`test`.`t1`.`a`) = `tvc_0`.`1`))))) explain extended select * from t1 where a not in (select * from (values (1),(2)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +2 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 4 func 1 100.00 Using where; Full scan on NULL key 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<`test`.`t1`.`a`>((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `tvc_0`.`1` from (values (1),(2)) `tvc_0` ), (`test`.`t1`.`a` in on distinct_key where `test`.`t1`.`a` = ``.`1`)))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<`test`.`t1`.`a`>((`test`.`t1`.`a`,(((`test`.`t1`.`a`) in on distinct_key where trigcond((`test`.`t1`.`a`) = `tvc_0`.`1`))))) # NOT IN subquery with VALUES structure(s) : UNION with VALUES on the first place select * from t1 where a not in (values (1) union select 2); @@ -978,21 +976,19 @@ a b explain extended select * from t1 where a = any (values (1),(2)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` explain extended select * from t1 where a = any (select * from (values (1),(2)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a` # ANY-subquery with VALUES structure(s) : UNION with VALUES on the first place select * from t1 where a = any (values (1) union select 2); @@ -1011,7 +1007,7 @@ explain extended select * from t1 where a = any (values (1) union select 2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -4 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +4 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL @@ -1022,7 +1018,7 @@ where a = any (select * from (values (1)) as tvc_0 union select 2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL @@ -1047,7 +1043,7 @@ where a = any (select 2 union values (1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -4 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +4 DEPENDENT UNION eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -1058,7 +1054,7 @@ select * from (values (1)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -3 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +3 DEPENDENT UNION ref key0 key0 4 func 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -1140,7 +1136,7 @@ where a = any (select 1 union values (1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -4 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +4 DEPENDENT UNION eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -1151,7 +1147,7 @@ select * from (values (1)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -3 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +3 DEPENDENT UNION ref key0 key0 4 func 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -2688,9 +2684,9 @@ a explain extended select a from t1 where a in (values (7) union values (8)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -4 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +4 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used -5 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +5 DEPENDENT UNION eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -2841,7 +2837,7 @@ id select_type table type possible_keys key key_len ref rows Extra 6 SUBQUERY ALL NULL NULL NULL NULL 2 2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used 3 SUBQUERY t3 ALL NULL NULL NULL NULL 11 Using where -3 SUBQUERY ref key0 key0 8 test.t3.a 2 Using where; FirstMatch(t3) +3 SUBQUERY ref key0 key0 8 test.t3.a 1 Using where; FirstMatch(t3) 5 DERIVED t3 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort prepare stmt from "select (values ((select * from t3 where a in (select * from v1))))"; @@ -2866,7 +2862,7 @@ id select_type table type possible_keys key key_len ref rows Extra 6 SUBQUERY ALL NULL NULL NULL NULL 2 2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used 3 SUBQUERY t3 ALL NULL NULL NULL NULL 11 Using where -3 SUBQUERY ref key0 key0 8 test.t3.a 2 Using where; FirstMatch(t3) +3 SUBQUERY ref key0 key0 8 test.t3.a 1 Using where; FirstMatch(t3) 5 DERIVED t3 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort prepare stmt from "select (values ((select * from t3 @@ -2951,6 +2947,8 @@ values ((values (4)), (select 5)), ((select 2), (values (8))); values ((values (1) union values (1))); (values (1) union values (1)) 1 +values ((values (1) union all values (1))); +ERROR 21000: Subquery returns more than 1 row values ((values (1) union values (1) union values (1))); (values (1) union values (1) union values (1)) 1 diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test index 331cfb8b7db..ade90400b63 100644 --- a/mysql-test/main/table_value_constr.test +++ b/mysql-test/main/table_value_constr.test @@ -422,6 +422,7 @@ select * from t2; --echo # recursive CTE that uses VALUES structure(s) : that uses UNION ALL +--sorted_result with recursive t2(a,b,st) as ( values(1,1,1) @@ -832,6 +833,7 @@ deallocate prepare stmt1; explain values (1,2); +--source include/explain-no-costs.inc explain format=json values (1,2); @@ -852,16 +854,19 @@ values (5,6) union values (1,2),(3,4); +--source include/explain-no-costs.inc explain format=json select 1,2 union values (1,2),(3,4); +--source include/explain-no-costs.inc explain format=json values (1,2),(3,4) union select 1,2; +--source include/explain-no-costs.inc explain format=json values (5,6) union @@ -874,6 +879,7 @@ values (3,4) union values (1,2); +--source include/explain-no-costs.inc explain format=json select 1,2 union @@ -898,16 +904,19 @@ values (1,2) union all values (1,2),(3,4); +--source include/explain-no-costs.inc explain format=json values (1,2),(3,4) union all select 1,2; +--source include/explain-no-costs.inc explain format=json select 1,2 union values (1,2),(3,4); +--source include/explain-no-costs.inc explain format=json values (1,2) union all @@ -920,6 +929,7 @@ values (3,4) union all values (1,2); +--source include/explain-no-costs.inc explain format=json select 1,2 union all @@ -1574,6 +1584,9 @@ values ((values (4)), (select 5)), ((select 2), (values (8))); values ((values (1) union values (1))); +--error ER_SUBQUERY_NO_1_ROW +values ((values (1) union all values (1))); + values ((values (1) union values (1) union values (1))); values ((values ((values (4))))); diff --git a/mysql-test/main/tmp_table_count-7586.result b/mysql-test/main/tmp_table_count-7586.result index 637e7385685..ebb2333113f 100644 --- a/mysql-test/main/tmp_table_count-7586.result +++ b/mysql-test/main/tmp_table_count-7586.result @@ -52,6 +52,7 @@ Created_tmp_disk_tables 0 Created_tmp_files 0 Created_tmp_tables 2 drop table t3; +set @@optimizer_switch="firstmatch=off"; EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 @@ -69,6 +70,7 @@ Variable_name Value Created_tmp_disk_tables 0 Created_tmp_files 0 Created_tmp_tables 1 +set @@optimizer_switch=default; drop table t1,t2,t3; truncate table performance_schema.events_statements_history_long; flush status; diff --git a/mysql-test/main/tmp_table_count-7586.test b/mysql-test/main/tmp_table_count-7586.test index 0629e27f164..8fe9e3d2eff 100644 --- a/mysql-test/main/tmp_table_count-7586.test +++ b/mysql-test/main/tmp_table_count-7586.test @@ -47,6 +47,7 @@ select sum(created_tmp_tables) from performance_schema.events_statements_history show status like '%Created_tmp%'; drop table t3; +set @@optimizer_switch="firstmatch=off"; EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a); truncate table performance_schema.events_statements_history_long; flush status; @@ -54,6 +55,7 @@ CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a); --echo # Performance schema should be the same as "Created_tmp_tables" variable below select sum(created_tmp_tables) from performance_schema.events_statements_history_long; show status like '%Created_tmp%'; +set @@optimizer_switch=default; drop table t1,t2,t3; diff --git a/mysql-test/main/trigger.result b/mysql-test/main/trigger.result index 410c5a53ce2..b3ab5585d92 100644 --- a/mysql-test/main/trigger.result +++ b/mysql-test/main/trigger.result @@ -736,8 +736,6 @@ select user() into user; set NEW.username = user; select count(*) from ((select 1) union (select 2)) as d1 into i; end| -Warnings: -Warning 1287 ' INTO FROM...' instead update t1 set data = 1; connection addconroot1; update t1 set data = 2; @@ -2086,8 +2084,6 @@ FOR EACH ROW BEGIN SELECT 1 FROM t1 c WHERE (@bug51650 IS NULL OR @bug51650 != c.b) AND c.b = NEW.a LIMIT 1 INTO @foo; END// -Warnings: -Warning 1287 ' INTO FROM...' instead SET @bug51650 = 1; INSERT IGNORE INTO t2 VALUES(); INSERT IGNORE INTO t1 SET b = '777'; diff --git a/mysql-test/main/type_blob.result b/mysql-test/main/type_blob.result index 851d0bd72d4..ccbbe5c9118 100644 --- a/mysql-test/main/type_blob.result +++ b/mysql-test/main/type_blob.result @@ -690,18 +690,18 @@ id txt 2 Chevy select * from t1 where txt > 'Chevy'; id txt -4 Honda -5 Subaru -6 Honda 7 Ford +4 Honda +6 Honda +5 Subaru select * from t1 where txt >= 'Chevy'; id txt 1 Chevy 2 Chevy -4 Honda -5 Subaru -6 Honda 7 Ford +4 Honda +6 Honda +5 Subaru alter table t1 modify column txt blob; explain select * from t1 where txt='Chevy' or txt is NULL; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/type_datetime.result b/mysql-test/main/type_datetime.result index 3e864d0ffa9..96f3c568446 100644 --- a/mysql-test/main/type_datetime.result +++ b/mysql-test/main/type_datetime.result @@ -545,7 +545,7 @@ select * from t1 where id in (select id from t1 as x1 where (t1.cur_date is null)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary; End temporary +1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1) Warnings: Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where `test`.`x1`.`id` = `test`.`t1`.`id` and `test`.`t1`.`cur_date` = 0 @@ -557,7 +557,7 @@ select * from t2 where id in (select id from t2 as x1 where (t2.cur_date is null)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary; End temporary +1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t2) Warnings: Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where `test`.`x1`.`id` = `test`.`t2`.`id` and `test`.`t2`.`cur_date` = 0 diff --git a/mysql-test/main/type_enum.result b/mysql-test/main/type_enum.result index 9e313f5b302..a935e3d63cb 100644 --- a/mysql-test/main/type_enum.result +++ b/mysql-test/main/type_enum.result @@ -2377,7 +2377,7 @@ t2 CREATE TABLE `t2` ( DROP TABLE t2; SELECT c_int FROM t1 UNION SELECT c_enum FROM t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def c_int c_int 253 11 0 Y 0 0 8 +def c_int c_int 253 11 0 Y 16384 0 8 c_int SELECT COALESCE(c_int, c_enum) FROM t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr diff --git a/mysql-test/main/type_ranges.result b/mysql-test/main/type_ranges.result index 02b6c79bdf5..012d1fc67ce 100644 --- a/mysql-test/main/type_ranges.result +++ b/mysql-test/main/type_ranges.result @@ -173,12 +173,12 @@ PRIMARY KEY (auto) ); INSERT IGNORE INTO t2 (string,mediumblob_col,new_field) SELECT string,mediumblob_col,new_field from t1 where auto > 10; Warnings: +Warning 1265 Data truncated for column 'new_field' at row 1 Warning 1265 Data truncated for column 'new_field' at row 2 Warning 1265 Data truncated for column 'new_field' at row 3 Warning 1265 Data truncated for column 'new_field' at row 4 Warning 1265 Data truncated for column 'new_field' at row 5 Warning 1265 Data truncated for column 'new_field' at row 6 -Warning 1265 Data truncated for column 'new_field' at row 7 select * from t2; auto string mediumblob_col new_field 1 2 2 ne diff --git a/mysql-test/main/type_set.result b/mysql-test/main/type_set.result index 571e0d36eaf..5821bbae984 100644 --- a/mysql-test/main/type_set.result +++ b/mysql-test/main/type_set.result @@ -403,7 +403,7 @@ t2 CREATE TABLE `t2` ( DROP TABLE t2; SELECT c_int FROM t1 UNION SELECT c_set FROM t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def c_int c_int 253 33 0 Y 0 0 33 +def c_int c_int 253 33 0 Y 16384 0 33 c_int SELECT COALESCE(c_int, c_set) FROM t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr diff --git a/mysql-test/main/type_time_6065.result b/mysql-test/main/type_time_6065.result index 56de96870b6..e0014ea75d9 100644 --- a/mysql-test/main/type_time_6065.result +++ b/mysql-test/main/type_time_6065.result @@ -220,7 +220,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key = col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where -1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 2 100.00 Using where; Using index +1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 1 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -241,7 +241,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key = col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where -1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 2 100.00 Using where; Using index +1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 1 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key` SELECT * FROM @@ -304,7 +304,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key = col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using where; Using index -1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 2 100.00 Using where; Using index +1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 1 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -325,7 +325,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key = col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using where; Using index -1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 2 100.00 Using where; Using index +1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 1 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key` SELECT * FROM @@ -408,7 +408,7 @@ t2 force INDEX (col_datetime_key) WHERE col_time_key >= col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -439,7 +439,7 @@ t2 force INDEX (col_datetime_key) WHERE col_datetime_key >= col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key` SELECT * FROM @@ -532,7 +532,7 @@ t2 force INDEX (col_datetime_key) WHERE col_time_key >= col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -563,7 +563,7 @@ t2 force INDEX (col_datetime_key) WHERE col_datetime_key >= col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key` SELECT * FROM @@ -656,7 +656,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key >= col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -687,7 +687,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key >= col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key` SELECT * FROM @@ -780,7 +780,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key >= col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using index -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -811,7 +811,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key >= col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using index -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key` SELECT * FROM @@ -894,7 +894,7 @@ t2 force INDEX (col_datetime_key) WHERE col_time_key > col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -920,7 +920,7 @@ t2 force INDEX (col_datetime_key) WHERE col_datetime_key > col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key` SELECT * FROM @@ -998,7 +998,7 @@ t2 force INDEX (col_datetime_key) WHERE col_time_key > col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1024,7 +1024,7 @@ t2 force INDEX (col_datetime_key) WHERE col_datetime_key > col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key` SELECT * FROM @@ -1102,7 +1102,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key > col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1128,7 +1128,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key > col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key` SELECT * FROM @@ -1206,7 +1206,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key > col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using index -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1232,7 +1232,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key > col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using index -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key` SELECT * FROM @@ -1320,7 +1320,7 @@ t2 force INDEX (col_datetime_key) WHERE col_time_key <= col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1351,7 +1351,7 @@ t2 force INDEX (col_datetime_key) WHERE col_datetime_key <= col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key` SELECT * FROM @@ -1444,7 +1444,7 @@ t2 force INDEX (col_datetime_key) WHERE col_time_key <= col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1475,7 +1475,7 @@ t2 force INDEX (col_datetime_key) WHERE col_datetime_key <= col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key` SELECT * FROM @@ -1568,7 +1568,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key <= col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1599,7 +1599,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key <= col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key` SELECT * FROM @@ -1692,7 +1692,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key <= col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using index -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1723,7 +1723,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key <= col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using index -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key` SELECT * FROM @@ -1806,7 +1806,7 @@ t2 force INDEX (col_datetime_key) WHERE col_time_key < col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1832,7 +1832,7 @@ t2 force INDEX (col_datetime_key) WHERE col_datetime_key < col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key` SELECT * FROM @@ -1910,7 +1910,7 @@ t2 force INDEX (col_datetime_key) WHERE col_time_key < col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -1936,7 +1936,7 @@ t2 force INDEX (col_datetime_key) WHERE col_datetime_key < col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index -1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where `test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key` SELECT * FROM @@ -2014,7 +2014,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key < col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -2040,7 +2040,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key < col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key` SELECT * FROM @@ -2118,7 +2118,7 @@ t1 force INDEX (col_time_key) WHERE col_time_key < col_datetime_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using index -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key` SELECT * FROM @@ -2144,7 +2144,7 @@ t1 force INDEX (col_time_key) WHERE col_datetime_key < col_time_key; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 index col_datetime_key col_datetime_key 6 NULL 5 100.00 Using index -1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1) +1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Range checked for each record (index map: 0x1); Using index Warnings: Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where `test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key` SELECT * FROM @@ -2267,9 +2267,8 @@ outr.col_varchar_key IS NULL ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY outr system col_datetime_key NULL NULL NULL 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 +1 PRIMARY innr ref col_int_key col_int_key 4 const 2 50.00 Using where; FirstMatch(outr) 1 PRIMARY outr2 index col_time_key col_time_key 4 NULL 20 100.00 Using where; Using index; Using join buffer (flat, BNL join) -2 MATERIALIZED innr ref col_int_key col_int_key 4 const 2 100.00 Using where Warnings: Note 1003 select 1 AS `col_int_nokey` from `test`.`t3` `outr2` semi join (`test`.`t1` `innr`) where `test`.`innr`.`col_int_key` = 1 and `test`.`innr`.`pk` >= `test`.`innr`.`col_int_nokey` and `test`.`outr2`.`col_time_key` > '2001-11-04 19:07:55' SELECT outr.col_int_nokey diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result index aab13d191a4..797abaf9de5 100644 --- a/mysql-test/main/union.result +++ b/mysql-test/main/union.result @@ -1541,8 +1541,6 @@ NULL (select 2) union (select 1 into @var); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'into @var)' at line 1 (select 1) union (select 1) into @var; -Warnings: -Warning 1287 ' INTO FROM...' instead (select 2) union (select 1) into @var; ERROR 42000: Result consisted of more than one row CREATE TABLE t1 (a int); @@ -1675,14 +1673,8 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FROM t1' at line 1 SELECT a FROM t1 UNION SELECT a FROM t1 INTO @v ; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT a FROM t1 UNION SELECT a FROM t1 INTO OUTFILE 'union.out.file5'; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT a FROM t1 UNION SELECT a FROM t1 INTO OUTFILE 'union.out.file6'; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UNION SELECT a FROM t1' at line 1 SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; @@ -2783,3 +2775,70 @@ drop table t1; # # End of 10.3 tests # + +# check union all & union disctinct + +select 1 as res union select 2 union select 1 union select 2; +res +1 +2 +select 1 as res union distinct select 2 union distinct select 1 union distinct select 2; +res +1 +2 +select 1 as res union all select 2 union all select 1 union all select 2; +res +1 +2 +1 +2 +select truncate(seq/2,0)+1 as res from seq_1_to_6 union select 2; +res +1 +2 +3 +4 +select truncate(seq/2,0)+1 as res from seq_1_to_6 union distinct select 2; +res +1 +2 +3 +4 +select truncate(seq/2,0)+1 as res from seq_1_to_6 union all select 2; +res +1 +2 +2 +3 +3 +4 +2 +select 1 as res union all select 2 union distinct select 1 union all select 2; +res +1 +2 +2 +select 1 as res union select 2 union all select 1 union distinct select 3; +res +1 +2 +3 +select 1 as res union select 2 union all select 1 union distinct select 3 union all select 2; +res +1 +2 +3 +2 +select 1 as res union select 2 union all select 1 union distinct select 3 union all select 2 union distinct select 5; +res +1 +2 +3 +5 +select truncate(seq/2,0)+1 as res from seq_1_to_6 union all select 2 union all select 1 union distinct select 3 union all select 2; +res +1 +2 +3 +4 +2 diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test index 4cebdcff9bb..98c36e0404a 100644 --- a/mysql-test/main/union.test +++ b/mysql-test/main/union.test @@ -1,6 +1,8 @@ # # Test of unions # +--source include/have_sequence.inc + CREATE TABLE t1 (a int not null, b char (10) not null); insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); @@ -2010,3 +2012,21 @@ drop table t1; --echo # --echo # End of 10.3 tests --echo # + +--echo +--echo # check union all & union disctinct +--echo + +select 1 as res union select 2 union select 1 union select 2; +select 1 as res union distinct select 2 union distinct select 1 union distinct select 2; +select 1 as res union all select 2 union all select 1 union all select 2; + +select truncate(seq/2,0)+1 as res from seq_1_to_6 union select 2; +select truncate(seq/2,0)+1 as res from seq_1_to_6 union distinct select 2; +select truncate(seq/2,0)+1 as res from seq_1_to_6 union all select 2; + +select 1 as res union all select 2 union distinct select 1 union all select 2; +select 1 as res union select 2 union all select 1 union distinct select 3; +select 1 as res union select 2 union all select 1 union distinct select 3 union all select 2; +select 1 as res union select 2 union all select 1 union distinct select 3 union all select 2 union distinct select 5; +select truncate(seq/2,0)+1 as res from seq_1_to_6 union all select 2 union all select 1 union distinct select 3 union all select 2; diff --git a/mysql-test/main/update_use_source.result b/mysql-test/main/update_use_source.result index 2774e7ee92d..91b2f7c8890 100644 --- a/mysql-test/main/update_use_source.result +++ b/mysql-test/main/update_use_source.result @@ -317,7 +317,7 @@ rollback; explain update t1 set c1=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 > 3; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 2 Using where -2 DEPENDENT SUBQUERY a ref t1_c2 t1_c2 5 test.t1.c2 4 Using index +2 DEPENDENT SUBQUERY a ref t1_c2 t1_c2 5 test.t1.c2 8 Using index start transaction; update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; affected rows: 4 diff --git a/mysql-test/main/userstat.result b/mysql-test/main/userstat.result index 5315317e33a..eec7910aae8 100644 --- a/mysql-test/main/userstat.result +++ b/mysql-test/main/userstat.result @@ -1,6 +1,4 @@ select variable_value from information_schema.global_status where variable_name="handler_read_key" into @global_read_key; -Warnings: -Warning 1287 ' INTO FROM...' instead show columns from information_schema.client_statistics; Field Type Null Key Default Extra CLIENT varchar(64) NO NULL diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index aec4a5d09f2..b5c5564a7da 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -2445,8 +2445,6 @@ SELECT Meaning FROM v1 INTO retn; RETURN retn; END // -Warnings: -Warning 1287 ' INTO FROM...' instead CREATE VIEW v2 AS SELECT f1(); select * from v2; f1() @@ -2618,8 +2616,6 @@ declare mx int; select max(a) from t1 into mx; return mx; end// -Warnings: -Warning 1287 ' INTO FROM...' instead create view v1 as select f1() as a; create view v2 as select * from v1; drop table t1; @@ -3162,14 +3158,10 @@ DROP VIEW v1; DROP TABLE t1; DROP VIEW IF EXISTS v1; SELECT * FROM (SELECT 1) AS t into @w; -Warnings: -Warning 1287 ' INTO FROM...' instead CREATE VIEW v1 AS SELECT * FROM (SELECT 1) AS t into @w; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'into @w' at line 1 # Previously the following would fail. SELECT * FROM (SELECT 1) AS t into @w; -Warnings: -Warning 1287 ' INTO FROM...' instead drop view if exists view_24532_a; drop view if exists view_24532_b; drop table if exists table_24532; @@ -3966,8 +3958,6 @@ BEGIN SELECT a FROM v2 INTO @a; RETURN @a; END// -Warnings: -Warning 1287 ' INTO FROM...' instead # Trigger pre-locking when opening v2. CREATE VIEW v1 AS SELECT f1() FROM t1; SHOW CREATE VIEW v1; @@ -4213,10 +4203,10 @@ INSERT INTO t2 VALUES EXPLAIN EXTENDED SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Using where -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 12 75.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Using where; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`pk` = `test`.`t1`.`a` and `test`.`t1`.`a` > 8 +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` = `test`.`t2`.`pk` and `test`.`t2`.`pk` > 8 FLUSH STATUS; SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8; a c @@ -4225,22 +4215,34 @@ a c SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value Handler_read_first 0 -Handler_read_key 1 +Handler_read_key 0 Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_retry 0 Handler_read_rnd 0 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 17 +Handler_read_rnd_next 30 +analyze table t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +explain extended SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 16 12.50 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`pk` = `test`.`t1`.`a` and `test`.`t1`.`a` > 8 CREATE VIEW v AS SELECT * FROM t2; EXPLAIN EXTENDED SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Using where -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 12 75.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Using where; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`pk` = `test`.`t1`.`a` and `test`.`t1`.`a` > 8 +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` = `test`.`t2`.`pk` and `test`.`t2`.`pk` > 8 FLUSH STATUS; SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8; a c @@ -4249,14 +4251,20 @@ a c SHOW STATUS LIKE 'Handler_read_%'; Variable_name Value Handler_read_first 0 -Handler_read_key 1 +Handler_read_key 0 Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_retry 0 Handler_read_rnd 0 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 17 +Handler_read_rnd_next 30 +set statement optimizer_where_cost=100 FOR explain extended SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`pk` = `test`.`t1`.`a` and `test`.`t1`.`a` > 8 DROP VIEW v; DROP TABLE t1, t2; # @@ -5481,8 +5489,8 @@ from t1 left join v1 on v1.c=t1.b where t1.a < 5; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 5 NULL 3 100.00 Using index condition -1 SIMPLE t2 ref c c 5 test.t1.b 2 100.00 Using where -1 SIMPLE t3 ref f,e e 5 test.t2.d 2 100.00 Using where +1 SIMPLE t2 ref c c 5 test.t1.b 1 100.00 Using where +1 SIMPLE t3 ref f,e e 5 test.t2.d 1 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`c` = `test`.`t1`.`b` and `test`.`t3`.`e` = `test`.`t2`.`d` and `test`.`t3`.`f` is not null and `test`.`t1`.`b` is not null and `test`.`t2`.`d` is not null) where `test`.`t1`.`a` < 5 explain extended @@ -5492,8 +5500,8 @@ on t2.c=t1.b and t3.f is not null where t1.a < 5; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 5 NULL 3 100.00 Using index condition -1 SIMPLE t2 ref c c 5 test.t1.b 2 100.00 Using where -1 SIMPLE t3 ref f,e e 5 test.t2.d 2 100.00 Using where +1 SIMPLE t2 ref c c 5 test.t1.b 1 100.00 Using where +1 SIMPLE t3 ref f,e e 5 test.t2.d 1 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`c` = `test`.`t1`.`b` and `test`.`t3`.`e` = `test`.`t2`.`d` and `test`.`t3`.`f` is not null and `test`.`t1`.`b` is not null and `test`.`t2`.`d` is not null) where `test`.`t1`.`a` < 5 explain extended @@ -5503,7 +5511,7 @@ where t1.a < 5; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 5 NULL 3 100.00 Using index condition 1 SIMPLE t3 eq_ref f,e f 4 test.t1.a 1 100.00 Using where -1 SIMPLE t2 ref c c 5 test.t1.b 2 100.00 Using where +1 SIMPLE t2 ref c c 5 test.t1.b 1 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`c` = `test`.`t1`.`b` and `test`.`t3`.`f` = `test`.`t1`.`a` and `test`.`t2`.`d` = `test`.`t3`.`e` and `test`.`t1`.`a` is not null and `test`.`t1`.`a` is not null and `test`.`t1`.`b` is not null) where `test`.`t1`.`a` < 5 explain extended @@ -5514,7 +5522,7 @@ where t1.a < 5; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 range a a 5 NULL 3 100.00 Using index condition 1 SIMPLE t3 eq_ref f,e f 4 test.t1.a 1 100.00 Using where -1 SIMPLE t2 ref c c 5 test.t1.b 2 100.00 Using where +1 SIMPLE t2 ref c c 5 test.t1.b 1 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`c` = `test`.`t1`.`b` and `test`.`t3`.`f` = `test`.`t1`.`a` and `test`.`t2`.`d` = `test`.`t3`.`e` and `test`.`t1`.`a` is not null and `test`.`t1`.`a` is not null and `test`.`t1`.`b` is not null) where `test`.`t1`.`a` < 5 drop view v1; diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index c6cc9a69f93..3b3d1124a09 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -1093,10 +1093,11 @@ insert into t1 values (1); update v2 set s1 = 1; select * from v2; select * from t2; -# scheck how VIEWs with subqueries work with prepared statements +# check how VIEWs with subqueries work with prepared statements prepare stmt1 from "select * from v2;"; execute stmt1; insert into t1 values (0); +--sorted_result execute stmt1; deallocate prepare stmt1; drop view v2; @@ -1880,7 +1881,9 @@ CREATE VIEW v1 AS SELECT id, f FROM t1 WHERE id <= 2; INSERT INTO t1 VALUES (2, 'foo2'); INSERT INTO t1 VALUES (1, 'foo1'); +--sorted_result SELECT * FROM v1; +--sorted_result SELECT * FROM v1; DROP VIEW v1; @@ -4162,12 +4165,18 @@ FLUSH STATUS; SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8; SHOW STATUS LIKE 'Handler_read_%'; +analyze table t1,t2; +explain extended SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8; + CREATE VIEW v AS SELECT * FROM t2; EXPLAIN EXTENDED SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8; FLUSH STATUS; SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8; SHOW STATUS LIKE 'Handler_read_%'; + +set statement optimizer_where_cost=100 FOR explain extended SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8; + DROP VIEW v; DROP TABLE t1, t2; diff --git a/mysql-test/main/view_grant.result b/mysql-test/main/view_grant.result index 112fccae07b..1c720f215f8 100644 --- a/mysql-test/main/view_grant.result +++ b/mysql-test/main/view_grant.result @@ -415,8 +415,6 @@ create table t2 (s1 int); drop function if exists f2; create function f2 () returns int begin declare v int; select s1 from t2 into v; return v; end// -Warnings: -Warning 1287 ' INTO FROM...' instead create algorithm=TEMPTABLE view v1 as select f2() from t1; create algorithm=MERGE view v2 as select f2() from t1; create algorithm=TEMPTABLE SQL SECURITY INVOKER view v3 as select f2() from t1; @@ -459,8 +457,6 @@ create table t2 (s1 int); drop function if exists f2; create function f2 () returns int begin declare v int; select s1 from t2 into v; return v; end// -Warnings: -Warning 1287 ' INTO FROM...' instead create user mysqltest_1@localhost; grant select on t1 to mysqltest_1@localhost; grant execute on function f2 to mysqltest_1@localhost; diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 9eb7c0d6029..04fa4c0bf16 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -1402,6 +1402,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1416,7 +1417,9 @@ EXPLAIN "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1437,6 +1440,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "window_functions_computation": { @@ -1453,7 +1457,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1474,6 +1480,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1488,7 +1495,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1511,6 +1520,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "MX in (3,5,7)", "filesort": { "sort_key": "t1.b", @@ -1528,7 +1538,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1665,6 +1677,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1679,7 +1692,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1697,6 +1712,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1711,7 +1727,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1729,6 +1747,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1743,7 +1762,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1761,6 +1782,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1775,7 +1797,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1821,6 +1845,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "row_number() over ( order by t1.s1,t1.s2) desc", "window_functions_computation": { @@ -1837,7 +1862,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 6, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1981,6 +2008,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "duplicate_removal": { "window_functions_computation": { "sorts": [ @@ -1996,7 +2024,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2161,6 +2191,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -2175,7 +2206,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2228,6 +2261,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -2242,7 +2276,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 6, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3827,6 +3863,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "window_functions_computation": { @@ -3849,9 +3886,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index d7f52ec32e9..56663a0ad88 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -927,11 +927,13 @@ drop table t0,t1; create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +--source include/explain-no-costs.inc explain format=json select rank() over (order by a) from t0; create table t1 (a int, b int, c int); insert into t1 select a,a,a from t0; +--source include/explain-no-costs.inc explain format=json select a, @@ -939,6 +941,7 @@ select from t1 group by a; +--source include/explain-no-costs.inc explain format=json select a, @@ -952,6 +955,7 @@ order by null; --echo # select b,max(a) as MX, rank() over (order by b) from t1 group by b having MX in (3,5,7); +--source include/explain-no-costs.inc explain format=json select b,max(a) as MX, rank() over (order by b) from t1 group by b having MX in (3,5,7); @@ -1040,24 +1044,28 @@ from t1; show status like '%sort%'; # Check using EXPLAIN FORMAT=JSON +--source include/explain-no-costs.inc explain format=json select rank() over (partition by c order by a), rank() over (partition by c order by a) from t1; +--source include/explain-no-costs.inc explain format=json select rank() over (order by a), row_number() over (order by a) from t1; +--source include/explain-no-costs.inc explain format=json select rank() over (partition by c order by a), count(*) over (partition by c) from t1; +--source include/explain-no-costs.inc explain format=json select count(*) over (partition by c), @@ -1089,6 +1097,7 @@ insert into t1 values (null,'a'); insert into t1 values (2,'b'); insert into t1 values (-1,''); +--source include/explain-no-costs.inc explain format=json select *, row_number() over (order by s1, s2) as X from t1 order by X desc; select *, row_number() over (order by s1, s2) as X from t1 order by X desc; @@ -1177,6 +1186,7 @@ insert into t1 values select rank() over (partition by part_id order by a) from t1; select distinct rank() over (partition by part_id order by a) from t1; +--source include/explain-no-costs.inc explain format=json select distinct rank() over (partition by part_id order by a) from t1; @@ -1301,6 +1311,7 @@ select pk, a, d, sum(d) over (order by a ROWS BETWEEN 1 preceding and 2 following) as sum_2 from t1; +--source include/explain-no-costs.inc explain format=json select pk, a, d, sum(d) over (partition by a order by pk @@ -1336,6 +1347,7 @@ insert into t1 values (10, 5, 1000), (10, 1, 100); +--source include/explain-no-costs.inc explain format=json select a,b,c, diff --git a/mysql-test/main/win_empty_over.result b/mysql-test/main/win_empty_over.result index 4fa53bb4eae..2f75f80c6ad 100644 --- a/mysql-test/main/win_empty_over.result +++ b/mysql-test/main/win_empty_over.result @@ -36,6 +36,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -53,7 +54,9 @@ EXPLAIN "key": "PRIMARY", "key_length": "4", "used_key_parts": ["pk"], + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "using_index": true } @@ -68,6 +71,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -85,7 +89,9 @@ EXPLAIN "key": "PRIMARY", "key_length": "4", "used_key_parts": ["pk"], + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100, "using_index": true } diff --git a/mysql-test/main/win_empty_over.test b/mysql-test/main/win_empty_over.test index 91344d76865..dff15a41e30 100644 --- a/mysql-test/main/win_empty_over.test +++ b/mysql-test/main/win_empty_over.test @@ -21,7 +21,9 @@ insert into t1 values (11, 2, 10, NULL, 0.9, NULL); select pk, row_number() over () from t1; +--source include/explain-no-costs.inc explain FORMAT=JSON select pk, row_number() over () from t1; +--source include/explain-no-costs.inc explain FORMAT=JSON select row_number() over (), pk from t1; select row_number() over () from (select 4) as t; diff --git a/mysql-test/main/xtradb_mrr.result b/mysql-test/main/xtradb_mrr.result index b4c91d9aff4..7d84f605e14 100644 --- a/mysql-test/main/xtradb_mrr.result +++ b/mysql-test/main/xtradb_mrr.result @@ -431,6 +431,12 @@ INSERT INTO `t1` VALUES (97,7,0,'z','z'); INSERT INTO `t1` VALUES (98,1,1,'j','j'); INSERT INTO `t1` VALUES (99,7,8,'c','c'); INSERT INTO `t1` VALUES (100,2,5,'f','f'); +EXPLAIN SELECT table1 .`col_varchar_key` +FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE table1 index NULL col_varchar_key 9 NULL # Using index +1 SIMPLE table3 ALL NULL NULL NULL NULL # Using where; Using join buffer (flat, BNL join) +1 SIMPLE table4 eq_ref PRIMARY PRIMARY 4 test.table3.col_int_nokey # Using where SELECT table1 .`col_varchar_key` FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ; col_varchar_key diff --git a/mysql-test/main/xtradb_mrr.test b/mysql-test/main/xtradb_mrr.test index 9de9b192b06..f5cecc54a3f 100644 --- a/mysql-test/main/xtradb_mrr.test +++ b/mysql-test/main/xtradb_mrr.test @@ -151,6 +151,9 @@ INSERT INTO `t1` VALUES (97,7,0,'z','z'); INSERT INTO `t1` VALUES (98,1,1,'j','j'); INSERT INTO `t1` VALUES (99,7,8,'c','c'); INSERT INTO `t1` VALUES (100,2,5,'f','f'); +--replace_column 9 # +EXPLAIN SELECT table1 .`col_varchar_key` +FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ; SELECT table1 .`col_varchar_key` FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ; DROP TABLE t1; diff --git a/mysql-test/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl index b7e83261298..5ab50a4f88b 100755 --- a/mysql-test/mariadb-test-run.pl +++ b/mysql-test/mariadb-test-run.pl @@ -516,12 +516,15 @@ sub main { if ( not @$completed ) { my $test_name= mtr_grab_file($path_testlog); - $test_name =~ s/^CURRENT_TEST:\s//; - chomp($test_name); - my $tinfo = My::Test->new(name => $test_name); - $tinfo->{result}= 'MTR_RES_FAILED'; - $tinfo->{comment}=' '; - mtr_report_test($tinfo); + if (defined($test_name)) + { + $test_name =~ s/^CURRENT_TEST:\s//; + chomp($test_name); + my $tinfo = My::Test->new(name => $test_name); + $tinfo->{result}= 'MTR_RES_FAILED'; + $tinfo->{comment}=' '; + mtr_report_test($tinfo); + } mtr_error("Test suite aborted"); } @@ -2713,6 +2716,7 @@ sub mysql_server_start($) { # Copy datadir from installed system db my $path= ($opt_parallel == 1) ? "$opt_vardir" : "$opt_vardir/.."; my $install_db= "$path/install.db"; + mtr_verbose("copying $install_db to $datadir"); copytree($install_db, $datadir) if -d $install_db; mtr_error("Failed to copy system db to '$datadir'") unless -d $datadir; } diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index 022b400fd97..0a6ec04fb31 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12488,6 +12488,10 @@ SELECT b FROM t5 WHERE a =3; b in order to form a more pefect union foo this is mine to think about +explain +SELECT b FROM t5 WHERE a IN (32, 23, 5); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t5 ALL a NULL NULL NULL 11 Using where SELECT b FROM t5 WHERE a IN (32, 23, 5); b foo grok diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index b6920827005..df5f6503321 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1445,8 +1445,9 @@ INSERT INTO t5 VALUES (NULL, "promote the general welfare"); SELECT * FROM t5; SELECT b FROM t5; SELECT b FROM t5 WHERE a =3; +explain +SELECT b FROM t5 WHERE a IN (32, 23, 5); SELECT b FROM t5 WHERE a IN (32, 23, 5); - #More blob tests diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index 0c0b0e77915..67849fc7fd1 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -2338,11 +2338,7 @@ Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. REPLACE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave UPDATE t1 SET a=1 LIMIT 1; -Warnings: -Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted DELETE FROM t1 LIMIT 1; -Warnings: -Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted CREATE PROCEDURE p1() BEGIN INSERT INTO t1 SELECT * FROM t1 LIMIT 1; diff --git a/mysql-test/suite/binlog/t/binlog_expire_warnings.opt b/mysql-test/suite/binlog/t/binlog_expire_warnings.opt new file mode 100644 index 00000000000..c85ef7d3e04 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_expire_warnings.opt @@ -0,0 +1 @@ +--log-warnings=4 diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test index f95fc0137a2..8ec3856dcb5 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test @@ -26,7 +26,7 @@ FLUSH LOGS; INSERT INTO t1 VALUES (1); # Read binlog data from master to intermediary result file ---let TIMEOUT=1 +--let TIMEOUT=5 --echo # timeout TIMEOUT MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=MASTER_MYPORT --stop-never --result-file=MYSQLTEST_VARDIR/tmp/ master-bin.000001 --error 124 # Error 124 means timeout was reached --exec timeout $TIMEOUT $MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --stop-never --result-file=$MYSQLTEST_VARDIR/tmp/ master-bin.000001 diff --git a/mysql-test/suite/binlog/t/binlog_truncate_multi_engine.test b/mysql-test/suite/binlog/t/binlog_truncate_multi_engine.test index 12b0a743916..61d097a8af7 100644 --- a/mysql-test/suite/binlog/t/binlog_truncate_multi_engine.test +++ b/mysql-test/suite/binlog/t/binlog_truncate_multi_engine.test @@ -12,6 +12,7 @@ --source include/have_debug.inc --source include/have_debug_sync.inc --source include/have_binlog_format_row.inc +--source include/not_valgrind.inc --let $old_max_binlog_size= `select @@global.max_binlog_size` call mtr.add_suppression("Can.t init tc log"); diff --git a/mysql-test/suite/compat/oracle/r/sp-package-innodb.result b/mysql-test/suite/compat/oracle/r/sp-package-innodb.result index 0ac357df5da..50eb2dc6cd0 100644 --- a/mysql-test/suite/compat/oracle/r/sp-package-innodb.result +++ b/mysql-test/suite/compat/oracle/r/sp-package-innodb.result @@ -23,8 +23,6 @@ a:=a+1; INSERT INTO t1 VALUES (a,'pkg1 initialization'); END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL pkg1.p1; SELECT * FROM t1 ORDER BY a; a routine diff --git a/mysql-test/suite/compat/oracle/r/sp-package.result b/mysql-test/suite/compat/oracle/r/sp-package.result index ef0acea5da1..ef4b3f5db1f 100644 --- a/mysql-test/suite/compat/oracle/r/sp-package.result +++ b/mysql-test/suite/compat/oracle/r/sp-package.result @@ -2062,8 +2062,6 @@ $$ CALL p1.p1(); @a 11 -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1.p1(); @a 12 @@ -2095,8 +2093,6 @@ BEGIN SELECT MAX(a) FROM t1 INTO @a; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1.p1(); @a 11 @@ -2130,8 +2126,6 @@ BEGIN SELECT 1 FROM t1 INTO @a; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1.p1(); ERROR 42S02: Table 'test.t1' doesn't exist SELECT p1.f1(); @@ -2690,9 +2684,6 @@ SELECT * FROM t1 INTO b; SELECT b.a, b.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead -Warning 1287 ' INTO FROM...' instead CALL p1.p1; b.a b.b 10 b diff --git a/mysql-test/suite/compat/oracle/r/sp-row.result b/mysql-test/suite/compat/oracle/r/sp-row.result index 0b23f303030..b3a0ae15711 100644 --- a/mysql-test/suite/compat/oracle/r/sp-row.result +++ b/mysql-test/suite/compat/oracle/r/sp-row.result @@ -2835,8 +2835,6 @@ SELECT * FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: The used SELECT statements have a different number of columns DROP TABLE t1; @@ -2851,8 +2849,6 @@ SELECT * FROM t1 INTO rec1, rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: Operand should contain 2 column(s) DROP TABLE t1; @@ -2867,8 +2863,6 @@ SELECT * FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); rec1.a rec1.b 10 b10 @@ -2884,8 +2878,6 @@ SELECT 10,'a','b' FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: The used SELECT statements have a different number of columns DROP TABLE t1; @@ -2900,8 +2892,6 @@ SELECT 10,'a' FROM t1 INTO rec1, rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: Operand should contain 2 column(s) DROP TABLE t1; @@ -2916,8 +2906,6 @@ SELECT * FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); rec1.a rec1.b 10 b10 @@ -2934,8 +2922,6 @@ SELECT * FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: The used SELECT statements have a different number of columns DROP TABLE t1; @@ -2951,8 +2937,6 @@ SELECT * FROM t1 INTO rec1, rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); ERROR 21000: Operand should contain 2 column(s) DROP TABLE t1; @@ -2968,8 +2952,6 @@ SELECT * FROM t1 INTO rec1; SELECT rec1.a, rec1.b; END; $$ -Warnings: -Warning 1287 ' INTO FROM...' instead CALL p1(); rec1.a rec1.b 10 b10 diff --git a/mysql-test/suite/compat/oracle/r/table_value_constr.result b/mysql-test/suite/compat/oracle/r/table_value_constr.result index af071433d0f..65e31761b90 100644 --- a/mysql-test/suite/compat/oracle/r/table_value_constr.result +++ b/mysql-test/suite/compat/oracle/r/table_value_constr.result @@ -565,12 +565,12 @@ where t1.a=t2.a and st<3 select * from t2; a b st 1 1 1 -1 2 2 1 1 2 -1 2 3 -1 2 3 1 1 3 1 1 3 +1 2 2 +1 2 3 +1 2 3 # recursive CTE that uses VALUES structure(s) : computation of factorial (first 10 elements) with recursive fact(n,f) as ( @@ -741,21 +741,19 @@ a b explain extended select * from t1 where a in (values (1)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" semi join ((values (1)) "tvc_0") where 1 +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from (values (1)) "tvc_0" join "test"."t1" where "tvc_0"."1" = "test"."t1"."a" explain extended select * from t1 where a in (select * from (values (1)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" semi join ((values (1)) "tvc_0") where 1 +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from (values (1)) "tvc_0" join "test"."t1" where "tvc_0"."1" = "test"."t1"."a" # IN-subquery with VALUES structure(s) : UNION with VALUES on the first place select * from t1 where a in (values (1) union select 2); @@ -774,7 +772,7 @@ explain extended select * from t1 where a in (values (1) union select 2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -4 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +4 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL @@ -785,7 +783,7 @@ where a in (select * from (values (1)) as tvc_0 union select 2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL @@ -810,7 +808,7 @@ where a in (select 2 union values (1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -4 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +4 DEPENDENT UNION eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -821,7 +819,7 @@ select * from (values (1)) tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -3 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +3 DEPENDENT UNION ref key0 key0 4 func 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -846,7 +844,7 @@ explain extended select * from t1 where a in (values (1) union all select b from t1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -4 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +4 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 6 100.00 Using where Warnings: @@ -856,7 +854,7 @@ where a in (select * from (values (1)) as tvc_0 union all select b from t1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 4 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 6 100.00 Using where Warnings: @@ -878,18 +876,18 @@ explain extended select * from t1 where a not in (values (1),(2)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +3 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 4 func 1 100.00 Using where; Full scan on NULL key 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<"test"."t1"."a">(("test"."t1"."a","test"."t1"."a" in ( (/* select#3 */ select "tvc_0"."1" from (values (1),(2)) "tvc_0" ), ("test"."t1"."a" in on distinct_key where "test"."t1"."a" = ""."1")))) +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<"test"."t1"."a">(("test"."t1"."a",((("test"."t1"."a") in on distinct_key where trigcond(("test"."t1"."a") = "tvc_0"."1"))))) explain extended select * from t1 where a not in (select * from (values (1),(2)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +2 DEPENDENT SUBQUERY unique_subquery distinct_key distinct_key 4 func 1 100.00 Using where; Full scan on NULL key 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<"test"."t1"."a">(("test"."t1"."a","test"."t1"."a" in ( (/* select#2 */ select "tvc_0"."1" from (values (1),(2)) "tvc_0" ), ("test"."t1"."a" in on distinct_key where "test"."t1"."a" = ""."1")))) +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<"test"."t1"."a">(("test"."t1"."a",((("test"."t1"."a") in on distinct_key where trigcond(("test"."t1"."a") = "tvc_0"."1"))))) # NOT IN subquery with VALUES structure(s) : UNION with VALUES on the first place select * from t1 where a not in (values (1) union select 2); @@ -976,21 +974,19 @@ a b explain extended select * from t1 where a = any (values (1),(2)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -3 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" semi join ((values (1),(2)) "tvc_0") where 1 +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from (values (1),(2)) "tvc_0" join "test"."t1" where "tvc_0"."1" = "test"."t1"."a" explain extended select * from t1 where a = any (select * from (values (1),(2)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 -2 MATERIALIZED ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" semi join ((values (1),(2)) "tvc_0") where 1 +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from (values (1),(2)) "tvc_0" join "test"."t1" where "tvc_0"."1" = "test"."t1"."a" # ANY-subquery with VALUES structure(s) : UNION with VALUES on the first place select * from t1 where a = any (values (1) union select 2); @@ -1009,7 +1005,7 @@ explain extended select * from t1 where a = any (values (1) union select 2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -4 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +4 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL @@ -1020,7 +1016,7 @@ where a = any (select * from (values (1)) as tvc_0 union select 2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where -2 DEPENDENT SUBQUERY ref key0 key0 4 func 2 100.00 +2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL @@ -1045,7 +1041,7 @@ where a = any (select 2 union values (1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -4 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +4 DEPENDENT UNION eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -1056,7 +1052,7 @@ select * from (values (1)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -3 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +3 DEPENDENT UNION ref key0 key0 4 func 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -1138,7 +1134,7 @@ where a = any (select 1 union values (1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -4 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +4 DEPENDENT UNION eq_ref distinct_key distinct_key 4 func 1 100.00 3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: @@ -1149,7 +1145,7 @@ select * from (values (1)) as tvc_0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -3 DEPENDENT UNION ref key0 key0 4 func 2 100.00 +3 DEPENDENT UNION ref key0 key0 4 func 1 100.00 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: diff --git a/mysql-test/suite/compat/oracle/r/update_innodb.result b/mysql-test/suite/compat/oracle/r/update_innodb.result index 1dae643eeff..0c9922fe19e 100644 --- a/mysql-test/suite/compat/oracle/r/update_innodb.result +++ b/mysql-test/suite/compat/oracle/r/update_innodb.result @@ -6,8 +6,6 @@ CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) engine=innodb; INSERT INTO t1 VALUES (1); START TRANSACTION; SELECT a AS a_con1 FROM t1 INTO @a FOR UPDATE; -Warnings: -Warning 1287 ' INTO FROM...' instead connect con2,localhost,root,,; SET sql_mode='ORACLE'; START TRANSACTION; @@ -16,8 +14,6 @@ connection default; UPDATE t1 SET a=a+100; COMMIT; connection con2; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT a AS con2 FROM t1; con2 101 diff --git a/mysql-test/suite/compat/oracle/t/table_value_constr.test b/mysql-test/suite/compat/oracle/t/table_value_constr.test index ca3c40bb7f9..7c1463e27af 100644 --- a/mysql-test/suite/compat/oracle/t/table_value_constr.test +++ b/mysql-test/suite/compat/oracle/t/table_value_constr.test @@ -424,6 +424,7 @@ select * from t2; --echo # recursive CTE that uses VALUES structure(s) : that uses UNION ALL +--sorted_result with recursive t2(a,b,st) as ( values(1,1,1) diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index 6fde6d2a41f..103d8740087 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -1408,6 +1408,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1422,7 +1423,9 @@ EXPLAIN "table": { "table_name": "t0", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1443,6 +1446,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "t1.a", "window_functions_computation": { @@ -1459,7 +1463,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1480,6 +1486,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1494,7 +1501,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1517,6 +1526,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "having_condition": "MX in (3,5,7)", "filesort": { "sort_key": "t1.b", @@ -1534,7 +1544,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 10, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1671,6 +1683,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1685,7 +1698,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1703,6 +1718,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1717,7 +1733,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1735,6 +1753,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1749,7 +1768,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1767,6 +1788,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -1781,7 +1803,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 3, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1827,6 +1851,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "filesort": { "sort_key": "row_number() over ( order by t1.s1,t1.s2) desc", "window_functions_computation": { @@ -1843,7 +1868,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 6, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -1987,6 +2014,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "duplicate_removal": { "window_functions_computation": { "sorts": [ @@ -2002,7 +2030,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 9, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2167,6 +2197,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -2181,7 +2212,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 11, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -2234,6 +2267,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "window_functions_computation": { "sorts": [ { @@ -2248,7 +2282,9 @@ EXPLAIN "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "rows": 6, + "cost": "COST_REPLACED", "filtered": 100 } } @@ -3833,6 +3869,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "window_functions_computation": { @@ -3855,9 +3892,11 @@ ANALYZE "table": { "table_name": "t1", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 3, "r_rows": 3, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, diff --git a/mysql-test/suite/engines/funcs/r/rpl_drop_db.result b/mysql-test/suite/engines/funcs/r/rpl_drop_db.result index 3712527afe4..1b132c20afc 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_drop_db.result +++ b/mysql-test/suite/engines/funcs/r/rpl_drop_db.result @@ -6,8 +6,6 @@ create database mysqltest1; create table mysqltest1.t1 (n int); insert into mysqltest1.t1 values (1); select * from mysqltest1.t1 into outfile 'mysqltest1/f1.txt'; -Warnings: -Warning 1287 ' INTO FROM...' instead create table mysqltest1.t2 (n int); create table mysqltest1.t3 (n int); drop database mysqltest1; diff --git a/mysql-test/suite/engines/funcs/r/rpl_misc_functions.result b/mysql-test/suite/engines/funcs/r/rpl_misc_functions.result index 302cf2351c2..6c20623d62b 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_misc_functions.result +++ b/mysql-test/suite/engines/funcs/r/rpl_misc_functions.result @@ -42,8 +42,6 @@ INSERT INTO t1 (col_a) VALUES (test_replication_sf()); INSERT INTO t1 (col_a) VALUES (test_replication_sf()); connection slave; select * from t1 into outfile "../../tmp/t1_slave.txt"; -Warnings: -Warning 1287 ' INTO FROM...' instead connection master; create temporary table t1_slave select * from t1 where 1=0; load data infile '../../tmp/t1_slave.txt' into table t1_slave; diff --git a/mysql-test/suite/engines/funcs/r/rpl_sp,myisam,mix.rdiff b/mysql-test/suite/engines/funcs/r/rpl_sp,myisam,mix.rdiff index da41283e42f..cbf297f8071 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_sp,myisam,mix.rdiff +++ b/mysql-test/suite/engines/funcs/r/rpl_sp,myisam,mix.rdiff @@ -1,5 +1,5 @@ ---- /home/alice/git/10.3/mysql-test/suite/engines/funcs/r/rpl_sp,myisam,mix.result~ 2021-03-19 17:27:12.935559866 +0100 -+++ /home/alice/git/10.3/mysql-test/suite/engines/funcs/r/rpl_sp,myisam,mix.reject 2021-03-19 17:27:14.071534938 +0100 +--- /home/alice/git/10.3/mysql-test/suite/engines/funcs/r/rpl_sp,myisam,mix.result~ ++++ /home/alice/git/10.3/mysql-test/suite/engines/funcs/r/rpl_sp,myisam,mix.reject @@ -126,12 +126,15 @@ show warnings; Level Code Message diff --git a/mysql-test/suite/engines/iuds/r/type_bit_iuds.result b/mysql-test/suite/engines/iuds/r/type_bit_iuds.result index 93ed7a9f162..6f48a430292 100644 --- a/mysql-test/suite/engines/iuds/r/type_bit_iuds.result +++ b/mysql-test/suite/engines/iuds/r/type_bit_iuds.result @@ -568,9 +568,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -1399,9 +1408,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -2252,10 +2270,17 @@ hex(c1) hex(c2) 1 3 2 2 3 3 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: -Warning 1264 Out of range value for column 'c2' at row 2 -Warning 1264 Out of range value for column 'c2' at row 3 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -3191,7 +3216,7 @@ hex(c1) hex(c2) 8 D 9 D A A -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; @@ -11797,9 +11822,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -12628,9 +12662,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -13481,10 +13524,17 @@ hex(c1) hex(c2) 1 3 2 2 3 3 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: -Warning 1264 Out of range value for column 'c2' at row 2 -Warning 1264 Out of range value for column 'c2' at row 3 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -14420,7 +14470,7 @@ hex(c1) hex(c2) 8 D 9 D A A -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; @@ -23032,9 +23082,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -23869,9 +23928,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -24722,10 +24790,17 @@ hex(c1) hex(c2) 1 3 2 2 3 3 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: -Warning 1264 Out of range value for column 'c2' at row 2 -Warning 1264 Out of range value for column 'c2' at row 3 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -25661,7 +25736,7 @@ hex(c1) hex(c2) 8 D 9 D A A -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; @@ -34273,9 +34348,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -35110,9 +35194,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -35969,10 +36062,17 @@ hex(c1) hex(c2) 1 3 2 2 3 3 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: -Warning 1264 Out of range value for column 'c2' at row 2 -Warning 1264 Out of range value for column 'c2' at row 3 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -36908,7 +37008,7 @@ hex(c1) hex(c2) 8 D 9 D A A -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; @@ -45520,9 +45620,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -46357,9 +46466,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -47216,10 +47334,17 @@ hex(c1) hex(c2) 1 3 2 2 3 3 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: -Warning 1264 Out of range value for column 'c2' at row 2 -Warning 1264 Out of range value for column 'c2' at row 3 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -48161,7 +48286,7 @@ hex(c1) hex(c2) 8 D 9 D A A -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; @@ -56781,9 +56906,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -57620,9 +57754,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -58481,10 +58624,17 @@ hex(c1) hex(c2) 1 3 2 2 3 3 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: -Warning 1264 Out of range value for column 'c2' at row 2 -Warning 1264 Out of range value for column 'c2' at row 3 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -59428,7 +59578,7 @@ hex(c1) hex(c2) 8 D 9 D A A -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; @@ -68059,9 +68209,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -68895,9 +69054,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -69753,10 +69921,17 @@ hex(c1) hex(c2) 1 3 2 2 3 3 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: -Warning 1264 Out of range value for column 'c2' at row 2 -Warning 1264 Out of range value for column 'c2' at row 3 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -70697,7 +70872,7 @@ hex(c1) hex(c2) 8 D 9 D A A -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; @@ -79322,9 +79497,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -80158,9 +80342,18 @@ UPDATE IGNORE t5 SET c2=c2+10 WHERE c1 IN (b'001',b'101',b'111'); SELECT hex(c1),hex(c2) FROM t5; hex(c1) hex(c2) 1 1 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -81016,10 +81209,17 @@ hex(c1) hex(c2) 1 3 2 2 3 3 -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: -Warning 1264 Out of range value for column 'c2' at row 2 -Warning 1264 Out of range value for column 'c2' at row 3 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 +Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; TRUNCATE t6; INSERT IGNORE INTO t5 VALUES (95, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),(75, 42), (108, 67), (79, 349), (59, 188), (69, 206), (49, 345), (118, 380),(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),(44, 307), (68, 454), (57, 135); @@ -81960,7 +82160,7 @@ hex(c1) hex(c2) 8 D 9 D A A -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; Warnings: Warning 1264 Out of range value for column 'c2' at row 1 TRUNCATE t5; diff --git a/mysql-test/suite/engines/iuds/t/type_bit_iuds.test b/mysql-test/suite/engines/iuds/t/type_bit_iuds.test index 8f48d50fad0..fac2505fd22 100644 --- a/mysql-test/suite/engines/iuds/t/type_bit_iuds.test +++ b/mysql-test/suite/engines/iuds/t/type_bit_iuds.test @@ -227,7 +227,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -513,7 +513,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -799,7 +799,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -1085,7 +1085,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -2515,7 +2515,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -2801,7 +2801,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -3087,7 +3087,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -3373,7 +3373,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -4803,7 +4803,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -5089,7 +5089,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -5375,7 +5375,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -5661,7 +5661,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -7091,7 +7091,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -7377,7 +7377,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -7663,7 +7663,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -7949,7 +7949,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -9379,7 +9379,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -9665,7 +9665,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -9951,7 +9951,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -10237,7 +10237,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -11667,7 +11667,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -11953,7 +11953,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -12239,7 +12239,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -12525,7 +12525,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -13956,7 +13956,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -14243,7 +14243,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -14530,7 +14530,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -14817,7 +14817,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -16252,7 +16252,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -16539,7 +16539,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -16826,7 +16826,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### @@ -17113,7 +17113,7 @@ SELECT hex(c1),hex(c2) FROM t5; # Update using eq_ref # EXPLAIN SELECT * FROM t5,t6 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; -UPDATE IGNORE t5,t6 SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; +UPDATE IGNORE t6 straight_join t5 force index(PRIMARY) SET t5.c2=t6.c1+t6.c2 WHERE t5.c1=t6.c1 AND t5.c2=t6.c2; ############# DELETE ########### diff --git a/mysql-test/suite/federated/federatedx.result b/mysql-test/suite/federated/federatedx.result index 49deff81c4c..4217f546b37 100644 --- a/mysql-test/suite/federated/federatedx.result +++ b/mysql-test/suite/federated/federatedx.result @@ -2357,6 +2357,21 @@ DROP TABLE t2_fed, t1, t2; set @@optimizer_switch=@save_optimizer_switch; DROP SERVER s; # End of 10.5 tests +# +# MDEV-30569: Assertion ...ha_table_flags() failed in Duplicate_weedout_picker::check_qep +# +create server s foreign data wrapper mysql options +(host "127.0.0.1", database "test", user "root", port $MASTER_MYPORT); +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t1_fed ENGINE=FEDERATED CONNECTION='s/t1'; +CREATE VIEW v AS SELECT * FROM t1_fed; +SELECT * FROM v WHERE a IN ( SELECT b FROM t2); +a +DROP TABLE t1_fed, t1, t2; +DROP SERVER s; connection master; DROP TABLE IF EXISTS federated.t1; DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/suite/federated/federatedx.test b/mysql-test/suite/federated/federatedx.test index 7e5a335b786..5e010fe9557 100644 --- a/mysql-test/suite/federated/federatedx.test +++ b/mysql-test/suite/federated/federatedx.test @@ -2090,4 +2090,25 @@ DROP SERVER s; --echo # End of 10.5 tests +--echo # +--echo # MDEV-30569: Assertion ...ha_table_flags() failed in Duplicate_weedout_picker::check_qep +--echo # + +evalp create server s foreign data wrapper mysql options + (host "127.0.0.1", database "test", user "root", port $MASTER_MYPORT); + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); + +CREATE TABLE t1_fed ENGINE=FEDERATED CONNECTION='s/t1'; +CREATE VIEW v AS SELECT * FROM t1_fed; + +SELECT * FROM v WHERE a IN ( SELECT b FROM t2); + +DROP TABLE t1_fed, t1, t2; +DROP SERVER s; + source include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index f2e2247bae1..34056d0c696 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -150,7 +150,7 @@ FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t WHERE federated.t3.name=t.name; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 7 -1 PRIMARY ref key0 key0 18 federated.t3.name 2 +1 PRIMARY ref key0 key0 18 federated.t3.name 1 2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL EXPLAIN FORMAT=JSON SELECT * @@ -160,12 +160,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "rows": 7, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -178,7 +181,9 @@ EXPLAIN "key_length": "18", "used_key_parts": ["name"], "ref": ["federated.t3.name"], - "rows": 2, + "loops": 7, + "rows": 1, + "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { @@ -199,7 +204,7 @@ FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t WHERE federated.t3.name=t.name; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 7 7.00 100.00 100.00 -1 PRIMARY ref key0 key0 18 federated.t3.name 2 0.00 100.00 100.00 +1 PRIMARY ref key0 key0 18 federated.t3.name 1 0.00 100.00 100.00 2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL SELECT * FROM federated.t3, (SELECT t1.name FROM federated.t1 @@ -216,7 +221,7 @@ FROM federated.t2 GROUP BY name)) t WHERE federated.t3.name=t.name; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 7 -1 PRIMARY ref key0 key0 18 federated.t3.name 2 +1 PRIMARY ref key0 key0 18 federated.t3.name 1 2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL ANALYZE FORMAT=JSON SELECT * @@ -231,6 +236,7 @@ ANALYZE }, "query_block": { "select_id": 1, + "cost": "REPLACED", "r_loops": 1, "r_total_time_ms": "REPLACED", "nested_loop": [ @@ -238,9 +244,11 @@ ANALYZE "table": { "table_name": "t3", "access_type": "ALL", + "loops": 1, "r_loops": 1, "rows": 7, "r_rows": 7, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -256,9 +264,11 @@ ANALYZE "key_length": "18", "used_key_parts": ["name"], "ref": ["federated.t3.name"], + "loops": 7, "r_loops": 7, - "rows": 2, + "rows": 1, "r_rows": 0, + "cost": "REPLACED", "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", "filtered": 100, @@ -298,7 +308,7 @@ SELECT * FROM federated.t1 WHERE id >= 5) t WHERE federated.t3.name=t.name; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 7 -1 PRIMARY ref key0 key0 18 federated.t3.name 2 +1 PRIMARY ref key1 key1 18 federated.t3.name 1 2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL # # MDEV-21887: federatedx crashes on SELECT ... INTO query in select_handler code @@ -364,12 +374,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "t5", "access_type": "ALL", + "loops": 1, "rows": 2, + "cost": "COST_REPLACED", "filtered": 100 } }, @@ -378,7 +391,9 @@ EXPLAIN "table": { "table_name": "", "access_type": "ALL", + "loops": 2, "rows": 5, + "cost": "COST_REPLACED", "filtered": 100 }, "buffer_type": "flat", diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test index f827c141f3d..566aee6a0d6 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.test +++ b/mysql-test/suite/federated/federatedx_create_handlers.test @@ -76,6 +76,7 @@ SELECT id FROM federated.t1 WHERE id < 5; EXPLAIN EXTENDED SELECT id FROM federated.t1 WHERE id < 5; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT id FROM federated.t1 WHERE id < 5; @@ -103,6 +104,7 @@ SELECT * FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t WHERE federated.t3.name=t.name; +--source include/explain-no-costs.inc EXPLAIN FORMAT=JSON SELECT * FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t @@ -177,6 +179,7 @@ explain select * from federated.t1 where name in (select name from federated.t2); +--source include/explain-no-costs.inc explain format=json select * from federated.t1 where name in (select name from federated.t2); @@ -196,6 +199,7 @@ select * from t5, where name in (select name from federated.t2) or name like 'foo%') as TQ; --echo # Must not show elements with select_id=3 +--source include/explain-no-costs.inc explain format=json select * from t5, (select id from federated.t1 diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index c88a3a9ac8d..be0d6aa7740 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -210,6 +210,19 @@ def information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA 10 NULL YES varc def information_schema KEY_COLUMN_USAGE TABLE_CATALOG 4 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL def information_schema KEY_COLUMN_USAGE TABLE_NAME 6 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL def information_schema KEY_COLUMN_USAGE TABLE_SCHEMA 5 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL +def information_schema OPTIMIZER_COSTS ENGINE 1 NULL NO varchar 192 576 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(192) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_DISK_READ_COST 2 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_DISK_READ_RATIO 8 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_INDEX_BLOCK_COPY_COST 3 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_COMPARE_COST 4 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_COPY_COST 5 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_LOOKUP_COST 6 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_NEXT_FIND_COST 7 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROWID_COMPARE_COST 12 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROWID_COPY_COST 13 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_COPY_COST 9 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_LOOKUP_COST 10 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_NEXT_FIND_COST 11 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) select NEVER NULL def information_schema OPTIMIZER_TRACE INSUFFICIENT_PRIVILEGES 4 NULL NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(1) select NEVER NULL def information_schema OPTIMIZER_TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(20) select NEVER NULL def information_schema OPTIMIZER_TRACE QUERY 1 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8mb3 utf8mb3_general_ci longtext select NEVER NULL @@ -761,6 +774,19 @@ NULL information_schema KEY_COLUMN_USAGE POSITION_IN_UNIQUE_CONSTRAINT bigint NU 3.0000 information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) 3.0000 information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) 3.0000 information_schema KEY_COLUMN_USAGE REFERENCED_COLUMN_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema OPTIMIZER_COSTS ENGINE varchar 192 576 utf8mb3 utf8mb3_general_ci varchar(192) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_DISK_READ_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_INDEX_BLOCK_COPY_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_COMPARE_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_COPY_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_LOOKUP_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_NEXT_FIND_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_DISK_READ_RATIO decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_COPY_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_LOOKUP_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_NEXT_FIND_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROWID_COMPARE_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROWID_COPY_COST decimal NULL NULL NULL NULL decimal(9,6) 1.0000 information_schema OPTIMIZER_TRACE QUERY longtext 4294967295 4294967295 utf8mb3 utf8mb3_general_ci longtext 1.0000 information_schema OPTIMIZER_TRACE TRACE longtext 4294967295 4294967295 utf8mb3 utf8mb3_general_ci longtext NULL information_schema OPTIMIZER_TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE int NULL NULL NULL NULL int(20) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index bb12a0c38df..f9906d3f177 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -210,6 +210,19 @@ def information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA 10 NULL YES varc def information_schema KEY_COLUMN_USAGE TABLE_CATALOG 4 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) NEVER NULL def information_schema KEY_COLUMN_USAGE TABLE_NAME 6 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL def information_schema KEY_COLUMN_USAGE TABLE_SCHEMA 5 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) NEVER NULL +def information_schema OPTIMIZER_COSTS ENGINE 1 NULL NO varchar 192 576 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(192) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_DISK_READ_COST 2 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_DISK_READ_RATIO 8 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_INDEX_BLOCK_COPY_COST 3 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_COMPARE_COST 4 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_COPY_COST 5 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_LOOKUP_COST 6 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_NEXT_FIND_COST 7 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROWID_COMPARE_COST 12 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROWID_COPY_COST 13 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_COPY_COST 9 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_LOOKUP_COST 10 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL +def information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_NEXT_FIND_COST 11 NULL NO decimal NULL NULL 9 6 NULL NULL NULL decimal(9,6) NEVER NULL def information_schema OPTIMIZER_TRACE INSUFFICIENT_PRIVILEGES 4 NULL NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(1) NEVER NULL def information_schema OPTIMIZER_TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(20) NEVER NULL def information_schema OPTIMIZER_TRACE QUERY 1 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8mb3 utf8mb3_general_ci longtext NEVER NULL @@ -761,6 +774,19 @@ NULL information_schema KEY_COLUMN_USAGE POSITION_IN_UNIQUE_CONSTRAINT bigint NU 3.0000 information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) 3.0000 information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) 3.0000 information_schema KEY_COLUMN_USAGE REFERENCED_COLUMN_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema OPTIMIZER_COSTS ENGINE varchar 192 576 utf8mb3 utf8mb3_general_ci varchar(192) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_DISK_READ_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_INDEX_BLOCK_COPY_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_COMPARE_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_COPY_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_LOOKUP_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_KEY_NEXT_FIND_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_DISK_READ_RATIO decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_COPY_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_LOOKUP_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROW_NEXT_FIND_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROWID_COMPARE_COST decimal NULL NULL NULL NULL decimal(9,6) +NULL information_schema OPTIMIZER_COSTS OPTIMIZER_ROWID_COPY_COST decimal NULL NULL NULL NULL decimal(9,6) 1.0000 information_schema OPTIMIZER_TRACE QUERY longtext 4294967295 4294967295 utf8mb3 utf8mb3_general_ci longtext 1.0000 information_schema OPTIMIZER_TRACE TRACE longtext 4294967295 4294967295 utf8mb3 utf8mb3_general_ci longtext NULL information_schema OPTIMIZER_TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE int NULL NULL NULL NULL int(20) diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index c18f733c86f..93ede4d08cc 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -514,6 +514,31 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME OPTIMIZER_COSTS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 11 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8mb3_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +MAX_INDEX_LENGTH #MIL# +TEMPORARY Y +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME OPTIMIZER_TRACE TABLE_TYPE SYSTEM VIEW ENGINE MYISAM_OR_MARIA @@ -1630,6 +1655,31 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME OPTIMIZER_COSTS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 11 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8mb3_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +MAX_INDEX_LENGTH #MIL# +TEMPORARY Y +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME OPTIMIZER_TRACE TABLE_TYPE SYSTEM VIEW ENGINE MYISAM_OR_MARIA diff --git a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result index c18f733c86f..93ede4d08cc 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result @@ -514,6 +514,31 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME OPTIMIZER_COSTS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 11 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8mb3_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +MAX_INDEX_LENGTH #MIL# +TEMPORARY Y +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME OPTIMIZER_TRACE TABLE_TYPE SYSTEM VIEW ENGINE MYISAM_OR_MARIA @@ -1630,6 +1655,31 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME OPTIMIZER_COSTS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 11 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8mb3_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +MAX_INDEX_LENGTH #MIL# +TEMPORARY Y +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME OPTIMIZER_TRACE TABLE_TYPE SYSTEM VIEW ENGINE MYISAM_OR_MARIA diff --git a/mysql-test/suite/galera/r/galera_ist_MDEV-28423,debug.rdiff b/mysql-test/suite/galera/r/galera_ist_MDEV-28423,debug.rdiff index 4eda9d7d045..32c3949b1c4 100644 --- a/mysql-test/suite/galera/r/galera_ist_MDEV-28423,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_ist_MDEV-28423,debug.rdiff @@ -1,5 +1,5 @@ ---- suite/galera/r/galera_ist_MDEV-28423.result 2022-06-13 09:40:33.073863796 +0300 -+++ suite/galera/r/galera_ist_MDEV-28423.reject 2022-06-13 09:58:59.936874991 +0300 +--- suite/galera/r/galera_ist_MDEV-28423.result ++++ suite/galera/r/galera_ist_MDEV-28423.reject @@ -517,3 +517,187 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_ist_MDEV-28583,debug.rdiff b/mysql-test/suite/galera/r/galera_ist_MDEV-28583,debug.rdiff index 1c33916330a..c1bc37fb202 100644 --- a/mysql-test/suite/galera/r/galera_ist_MDEV-28583,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_ist_MDEV-28583,debug.rdiff @@ -1,5 +1,5 @@ ---- suite/galera/r/galera_ist_MDEV-28583.result 2022-06-11 10:48:16.875034382 +0300 -+++ suite/galera/r/galera_ist_MDEV-28583,debug.reject 2022-06-11 11:25:55.616481509 +0300 +--- suite/galera/r/galera_ist_MDEV-28583.result ++++ suite/galera/r/galera_ist_MDEV-28583,debug.reject @@ -517,3 +517,187 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_ist_mariabackup,debug.rdiff b/mysql-test/suite/galera/r/galera_ist_mariabackup,debug.rdiff index adf12c23e4a..243b2a50b2a 100644 --- a/mysql-test/suite/galera/r/galera_ist_mariabackup,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_ist_mariabackup,debug.rdiff @@ -1,5 +1,5 @@ ---- r/galera_ist_mariabackup.result 2021-04-10 14:21:16.141724901 +0300 -+++ r/galera_ist_mariabackup,debug.reject 2021-04-10 14:49:04.455785652 +0300 +--- r/galera_ist_mariabackup.result ++++ r/galera_ist_mariabackup,debug.reject @@ -517,3 +517,187 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_ist_mariabackup_innodb_flush_logs,debug.rdiff b/mysql-test/suite/galera/r/galera_ist_mariabackup_innodb_flush_logs,debug.rdiff index c9457d70812..b7a91b010fe 100644 --- a/mysql-test/suite/galera/r/galera_ist_mariabackup_innodb_flush_logs,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_ist_mariabackup_innodb_flush_logs,debug.rdiff @@ -1,5 +1,5 @@ ---- r/galera_ist_mariabackup_innodb_flush_logs.result 2021-04-10 14:21:52.661886653 +0300 -+++ r/galera_ist_mariabackup_innodb_flush_logs,debug.reject 2021-04-10 14:49:56.740062774 +0300 +--- r/galera_ist_mariabackup_innodb_flush_logs.result ++++ r/galera_ist_mariabackup_innodb_flush_logs,debug.reject @@ -172,3 +172,187 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_ist_rsync,debug.rdiff b/mysql-test/suite/galera/r/galera_ist_rsync,debug.rdiff index e76b37838fb..f3df998be95 100644 --- a/mysql-test/suite/galera/r/galera_ist_rsync,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_ist_rsync,debug.rdiff @@ -1,5 +1,5 @@ ---- r/galera_ist_rsync.result 2021-04-10 14:24:05.942467091 +0300 -+++ r/galera_ist_rsync,debug.reject 2021-04-10 14:52:14.236776538 +0300 +--- r/galera_ist_rsync.result ++++ r/galera_ist_rsync,debug.reject @@ -517,3 +517,187 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_many_indexes.result b/mysql-test/suite/galera/r/galera_many_indexes.result index 963d3552252..c0eabffd06d 100644 --- a/mysql-test/suite/galera/r/galera_many_indexes.result +++ b/mysql-test/suite/galera/r/galera_many_indexes.result @@ -74,7 +74,7 @@ LENGTH(f1) = 767 1 EXPLAIN SELECT COUNT(*) = 1 FROM t1 FORCE KEY (PRIMARY) WHERE f1 = REPEAT('a', 767); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 const PRIMARY PRIMARY 769 const 1 Using index +1 SIMPLE t1 const PRIMARY PRIMARY 769 const 1 SELECT COUNT(*) = 1 FROM t1 FORCE KEY (PRIMARY) WHERE f1 = REPEAT('a', 767); COUNT(*) = 1 1 diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup_data_dir,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_mariabackup_data_dir,debug.rdiff index 870b12de3c9..875d53addd8 100644 --- a/mysql-test/suite/galera/r/galera_sst_mariabackup_data_dir,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_sst_mariabackup_data_dir,debug.rdiff @@ -1,5 +1,5 @@ ---- r/galera_sst_mariabackup_data_dir.result 2021-04-10 14:26:02.798965488 +0300 -+++ r/galera_sst_mariabackup_data_dir,debug.reject 2021-04-10 14:54:44.825538224 +0300 +--- r/galera_sst_mariabackup_data_dir.result ++++ r/galera_sst_mariabackup_data_dir,debug.reject @@ -516,5 +516,189 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery,debug.rdiff index bad8355b514..da294317c27 100644 --- a/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery,debug.rdiff @@ -1,5 +1,5 @@ ---- r/galera_sst_mariabackup.result 2021-04-10 14:25:04.142716409 +0300 -+++ r/galera_sst_mariabackup,debug.reject 2021-04-10 14:53:30.033162191 +0300 +--- r/galera_sst_mariabackup.result ++++ r/galera_sst_mariabackup,debug.reject @@ -516,5 +516,189 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_sst_rsync2,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_rsync2,debug.rdiff index 14f67770572..ae242e2b216 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync2,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_sst_rsync2,debug.rdiff @@ -1,5 +1,5 @@ ---- r/galera_sst_rsync2.result 2021-04-10 14:34:48.646288119 +0300 -+++ r/galera_sst_rsync2,debug.reject 2021-04-10 15:04:10.276286996 +0300 +--- r/galera_sst_rsync2.result ++++ r/galera_sst_rsync2,debug.reject @@ -516,3 +516,187 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_data_dir,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_rsync_data_dir,debug.rdiff index 00b42d53b51..558a8e7cd07 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_data_dir,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_sst_rsync_data_dir,debug.rdiff @@ -1,5 +1,5 @@ ---- r/galera_sst_rsync_data_dir.result 2021-04-10 14:35:28.090610315 +0300 -+++ r/galera_sst_rsync_data_dir,debug.reject 2021-04-10 15:50:26.945234998 +0300 +--- r/galera_sst_rsync_data_dir.result ++++ r/galera_sst_rsync_data_dir,debug.reject @@ -516,3 +516,187 @@ 1 DROP TABLE t1; diff --git a/mysql-test/suite/gcol/inc/gcol_keys.inc b/mysql-test/suite/gcol/inc/gcol_keys.inc index e5ac0afd92a..9996d23e42e 100644 --- a/mysql-test/suite/gcol/inc/gcol_keys.inc +++ b/mysql-test/suite/gcol/inc/gcol_keys.inc @@ -14,6 +14,8 @@ # Change: # ################################################################################ +--source include/have_sequence.inc + if (!$support_virtual_index) { let $skip_spatial_index_check=1; let $skip_foreign_key_check=1; @@ -197,12 +199,16 @@ PRIMARY KEY (pk), KEY (col_time_key), KEY (col_datetime_key)); +--disable_warnings INSERT INTO c ( col_time_nokey,col_datetime_nokey,col_varchar_nokey) values ('14:03:03.042673','2001-11-28 00:50:27.051028', 'c'), ('01:46:09.016386','2007-10-09 19:53:04.008332', NULL), ('16:21:18.052408','2001-11-08 21:02:12.009395', 'x'), ('18:56:33.027423','2003-04-01 00:00:00', 'i'); +insert into c (col_time_nokey,col_datetime_nokey,col_varchar_nokey) select '10:10:10', '2021-12-24 01:50:27', 'z' from seq_1_to_10; +--enable_warnings + --replace_column 9 x 10 x EXPLAIN SELECT outr.col_time_key AS x diff --git a/mysql-test/suite/gcol/inc/gcol_select.inc b/mysql-test/suite/gcol/inc/gcol_select.inc index 2386c55fdbc..4c030cb5646 100644 --- a/mysql-test/suite/gcol/inc/gcol_select.inc +++ b/mysql-test/suite/gcol/inc/gcol_select.inc @@ -545,11 +545,11 @@ CREATE TABLE cc ( ); INSERT INTO cc (col_int_nokey) VALUES (0),(1),(7),(0),(4),(5); --replace_column 9 # 10 # -EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3; -SELECT pk FROM cc WHERE col_int_key > 3; +EXPLAIN SELECT pk FROM cc force index(col_int_key) WHERE col_int_key > 3; +SELECT pk FROM cc force index(col_int_key) WHERE col_int_key > 3; --replace_column 9 # 10 # -EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; -SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; +EXPLAIN SELECT pk FROM cc force index(col_int_key) WHERE col_int_key > 3 ORDER BY 1; +SELECT pk FROM cc force index(col_int_key) WHERE col_int_key > 3 ORDER BY 1; DROP TABLE cc; --echo # diff --git a/mysql-test/suite/gcol/r/gcol_bugfixes.result b/mysql-test/suite/gcol/r/gcol_bugfixes.result index f124ebe611c..7b70f61df03 100644 --- a/mysql-test/suite/gcol/r/gcol_bugfixes.result +++ b/mysql-test/suite/gcol/r/gcol_bugfixes.result @@ -638,10 +638,10 @@ DEFAULT SUBSTRING_INDEX(USER(),'@',1) ); EXPLAIN UPDATE gafld SET nuigafld = 0 WHERE nuigafld = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gafld ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE EXPLAIN UPDATE gafld SET nuigafld = 0 WHERE nuigafld = 10; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gafld ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DROP TABLE gafld; # (duplicate) MDEV-17653 replace into generated columns is unstable # Some columns are snipped from the MDEV test diff --git a/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result b/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result index 193ef064da8..bc3b5493dbd 100644 --- a/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_ins_upd_innodb.result @@ -497,7 +497,7 @@ WHERE OUTR1.pk = 1 id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY OUTR1 const PRIMARY PRIMARY 4 const 1 1 PRIMARY INNR1 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(OUTR1) -1 PRIMARY OUTR2 index NULL PRIMARY 4 NULL 2 Using index +1 PRIMARY OUTR2 ALL NULL NULL NULL NULL 2 DROP TABLE IF EXISTS b,bb,d; # # Bug#21216067 ASSERTION FAILED ROW_UPD_SEC_INDEX_ENTRY (INNOBASE/ROW/ROW0UPD.CC:2103) diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result index 0228f9be842..4b1e5b48327 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result @@ -192,11 +192,7 @@ INSERT INTO c ( col_time_nokey,col_datetime_nokey,col_varchar_nokey) values ('01:46:09.016386','2007-10-09 19:53:04.008332', NULL), ('16:21:18.052408','2001-11-08 21:02:12.009395', 'x'), ('18:56:33.027423','2003-04-01 00:00:00', 'i'); -Warnings: -Note 1265 Data truncated for column 'col_time_key' at row 1 -Note 1265 Data truncated for column 'col_time_key' at row 2 -Note 1265 Data truncated for column 'col_time_key' at row 3 -Note 1265 Data truncated for column 'col_time_key' at row 4 +insert into c (col_time_nokey,col_datetime_nokey,col_varchar_nokey) select '10:10:10', '2021-12-24 01:50:27', 'z' from seq_1_to_10; EXPLAIN SELECT outr.col_time_key AS x FROM c as outr diff --git a/mysql-test/suite/gcol/r/gcol_keys_myisam.result b/mysql-test/suite/gcol/r/gcol_keys_myisam.result index 523ff3a3764..3c9093cf9cd 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_keys_myisam.result @@ -192,11 +192,7 @@ INSERT INTO c ( col_time_nokey,col_datetime_nokey,col_varchar_nokey) values ('01:46:09.016386','2007-10-09 19:53:04.008332', NULL), ('16:21:18.052408','2001-11-08 21:02:12.009395', 'x'), ('18:56:33.027423','2003-04-01 00:00:00', 'i'); -Warnings: -Note 1265 Data truncated for column 'col_time_key' at row 1 -Note 1265 Data truncated for column 'col_time_key' at row 2 -Note 1265 Data truncated for column 'col_time_key' at row 3 -Note 1265 Data truncated for column 'col_time_key' at row 4 +insert into c (col_time_nokey,col_datetime_nokey,col_varchar_nokey) select '10:10:10', '2021-12-24 01:50:27', 'z' from seq_1_to_10; EXPLAIN SELECT outr.col_time_key AS x FROM c as outr diff --git a/mysql-test/suite/gcol/r/gcol_select_innodb.result b/mysql-test/suite/gcol/r/gcol_select_innodb.result index 72d1e9f320c..b57aceac9e0 100644 --- a/mysql-test/suite/gcol/r/gcol_select_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_select_innodb.result @@ -146,7 +146,7 @@ count(distinct c) 3 explain select count(distinct c) from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL c 5 NULL 6 Using index for group-by +1 SIMPLE t1 range NULL c 5 NULL 5 Using index for group-by ### ### filesort & range-based utils ### @@ -699,11 +699,10 @@ WHERE t4.c1 < 'o' ) AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN @@ -754,11 +753,10 @@ WHERE t4.c1 < 'o' ) AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN @@ -810,11 +808,10 @@ WHERE t4.c1 < 'o' ) AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN @@ -874,11 +871,10 @@ WHERE t4.c1 < 'o' ) AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1, t3.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN diff --git a/mysql-test/suite/gcol/r/gcol_select_myisam.result b/mysql-test/suite/gcol/r/gcol_select_myisam.result index 0d18976f3bf..070808fec4f 100644 --- a/mysql-test/suite/gcol/r/gcol_select_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_select_myisam.result @@ -146,7 +146,7 @@ count(distinct c) 3 explain select count(distinct c) from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL c 5 NULL 6 Using index for group-by +1 SIMPLE t1 range NULL c 5 NULL 5 Using index for group-by ### ### filesort & range-based utils ### @@ -792,18 +792,18 @@ PRIMARY KEY (pk), KEY (col_int_key) ); INSERT INTO cc (col_int_nokey) VALUES (0),(1),(7),(0),(4),(5); -EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3; +EXPLAIN SELECT pk FROM cc force index(col_int_key) WHERE col_int_key > 3; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE cc range col_int_key col_int_key 5 NULL # # -SELECT pk FROM cc WHERE col_int_key > 3; +SELECT pk FROM cc force index(col_int_key) WHERE col_int_key > 3; pk 5 6 3 -EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; +EXPLAIN SELECT pk FROM cc force index(col_int_key) WHERE col_int_key > 3 ORDER BY 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE cc range col_int_key col_int_key 5 NULL # # -SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; +SELECT pk FROM cc force index(col_int_key) WHERE col_int_key > 3 ORDER BY 1; pk 3 5 @@ -1325,11 +1325,10 @@ WHERE t4.c1 < 'o' ) AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN @@ -1381,11 +1380,10 @@ WHERE t4.c1 < 'o' ) AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY,v_idx,v_idx2 PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY,v_idx,v_idx2 PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN @@ -1439,11 +1437,10 @@ WHERE t4.c1 < 'o' ) AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY,v_idx2 PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY,v_idx2 PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN @@ -1506,11 +1503,10 @@ WHERE t4.c1 < 'o' ) AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY ALL distinct_key NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1, t3.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN diff --git a/mysql-test/suite/handler/aria.result b/mysql-test/suite/handler/aria.result index b0a4a173289..abed2cfccc7 100644 --- a/mysql-test/suite/handler/aria.result +++ b/mysql-test/suite/handler/aria.result @@ -1540,8 +1540,6 @@ BEGIN SELECT 1 FROM t2 INTO @a; RETURN 1; END| -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT f1(); ERROR 42S02: Table 'test.t2' doesn't exist CREATE TABLE t1(a INT); diff --git a/mysql-test/suite/handler/heap.result b/mysql-test/suite/handler/heap.result index e66bccb1341..75355ba029c 100644 --- a/mysql-test/suite/handler/heap.result +++ b/mysql-test/suite/handler/heap.result @@ -1539,8 +1539,6 @@ BEGIN SELECT 1 FROM t2 INTO @a; RETURN 1; END| -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT f1(); ERROR 42S02: Table 'test.t2' doesn't exist CREATE TABLE t1(a INT); diff --git a/mysql-test/suite/handler/innodb.result b/mysql-test/suite/handler/innodb.result index 5d44642db01..5305a80ab9e 100644 --- a/mysql-test/suite/handler/innodb.result +++ b/mysql-test/suite/handler/innodb.result @@ -1544,8 +1544,6 @@ BEGIN SELECT 1 FROM t2 INTO @a; RETURN 1; END| -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT f1(); ERROR 42S02: Table 'test.t2' doesn't exist CREATE TABLE t1(a INT); diff --git a/mysql-test/suite/handler/myisam.result b/mysql-test/suite/handler/myisam.result index cc817ccd889..94c3791d837 100644 --- a/mysql-test/suite/handler/myisam.result +++ b/mysql-test/suite/handler/myisam.result @@ -1540,8 +1540,6 @@ BEGIN SELECT 1 FROM t2 INTO @a; RETURN 1; END| -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT f1(); ERROR 42S02: Table 'test.t2' doesn't exist CREATE TABLE t1(a INT); diff --git a/mysql-test/suite/heap/heap_btree.result b/mysql-test/suite/heap/heap_btree.result index 526c76a52e8..3eb618a0680 100644 --- a/mysql-test/suite/heap/heap_btree.result +++ b/mysql-test/suite/heap/heap_btree.result @@ -70,6 +70,10 @@ alter table t1 engine=myisam; explain select * from t1 where a in (869751,736494,226312,802616); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range uniq_id uniq_id 4 NULL 4 Using where; Using index +insert into t1 values (1),(2),(3),(4),(5),(6); +explain select * from t1 where a in (869751,736494,226312,802616); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range uniq_id uniq_id 4 NULL 4 Using where; Using index drop table t1; create table t1 (x int not null, y int not null, key x using BTREE (x,y), unique y using BTREE (y)) engine=heap; diff --git a/mysql-test/suite/heap/heap_btree.test b/mysql-test/suite/heap/heap_btree.test index d3fbe4cc0d2..e8f7c02c6f3 100644 --- a/mysql-test/suite/heap/heap_btree.test +++ b/mysql-test/suite/heap/heap_btree.test @@ -48,6 +48,8 @@ select * from t1 where a in (869751,736494,226312,802616); explain select * from t1 where a in (869751,736494,226312,802616); alter table t1 engine=myisam; explain select * from t1 where a in (869751,736494,226312,802616); +insert into t1 values (1),(2),(3),(4),(5),(6); +explain select * from t1 where a in (869751,736494,226312,802616); drop table t1; create table t1 (x int not null, y int not null, key x using BTREE (x,y), unique y using BTREE (y)) diff --git a/mysql-test/suite/innodb/r/alter_algorithm,INPLACE.rdiff b/mysql-test/suite/innodb/r/alter_algorithm,INPLACE.rdiff index a176a9af29e..79b3d8854fa 100644 --- a/mysql-test/suite/innodb/r/alter_algorithm,INPLACE.rdiff +++ b/mysql-test/suite/innodb/r/alter_algorithm,INPLACE.rdiff @@ -1,5 +1,5 @@ ---- alter_algorithm.result 2020-04-30 21:39:48.923115511 +0530 -+++ alter_algorithm.reject 2020-04-30 21:45:04.131642093 +0530 +--- alter_algorithm.result ++++ alter_algorithm.reject @@ -7,43 +7,43 @@ INSERT INTO t1(f1, f2, f3) VALUES(1, 1, 1); SELECT @@alter_algorithm; diff --git a/mysql-test/suite/innodb/r/alter_algorithm,INSTANT.rdiff b/mysql-test/suite/innodb/r/alter_algorithm,INSTANT.rdiff index 414b7dc8b0c..fbcb5ca8704 100644 --- a/mysql-test/suite/innodb/r/alter_algorithm,INSTANT.rdiff +++ b/mysql-test/suite/innodb/r/alter_algorithm,INSTANT.rdiff @@ -1,5 +1,5 @@ ---- alter_algorithm.result 2020-04-30 21:39:48.923115511 +0530 -+++ alter_algorithm.reject 2020-04-30 21:47:08.245465018 +0530 +--- alter_algorithm.result ++++ alter_algorithm.reject @@ -7,43 +7,35 @@ INSERT INTO t1(f1, f2, f3) VALUES(1, 1, 1); SELECT @@alter_algorithm; diff --git a/mysql-test/suite/innodb/r/alter_algorithm,NOCOPY.rdiff b/mysql-test/suite/innodb/r/alter_algorithm,NOCOPY.rdiff index 2aa8c72265a..44e9f63a5f4 100644 --- a/mysql-test/suite/innodb/r/alter_algorithm,NOCOPY.rdiff +++ b/mysql-test/suite/innodb/r/alter_algorithm,NOCOPY.rdiff @@ -1,5 +1,5 @@ ---- alter_algorithm.result 2020-04-30 21:39:48.923115511 +0530 -+++ alter_algorithm.reject 2020-04-30 21:52:10.785967739 +0530 +--- alter_algorithm.result ++++ alter_algorithm.reject @@ -7,43 +7,35 @@ INSERT INTO t1(f1, f2, f3) VALUES(1, 1, 1); SELECT @@alter_algorithm; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff index 44446602b9f..b19abb449ad 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff @@ -1,5 +1,5 @@ ---- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530 -+++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:29:25.129637040 +0530 +--- mysql-test/suite/innodb/r/check_ibd_filesize.result ++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject @@ -3,18 +3,12 @@ # SPACE IN 5.7 THAN IN 5.6 # diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff index ef55ad971fe..a1011a1cb90 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff @@ -1,5 +1,5 @@ ---- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530 -+++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:31:39.288769153 +0530 +--- mysql-test/suite/innodb/r/check_ibd_filesize.result ++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject @@ -3,18 +3,18 @@ # SPACE IN 5.7 THAN IN 5.6 # diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff index bcdcea31160..010eb8a284d 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff @@ -1,5 +1,5 @@ ---- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530 -+++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:30:28.957174270 +0530 +--- mysql-test/suite/innodb/r/check_ibd_filesize.result ++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject @@ -3,18 +3,12 @@ # SPACE IN 5.7 THAN IN 5.6 # diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff index 7b699ef4cea..0e1e64724b0 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff @@ -1,5 +1,5 @@ ---- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530 -+++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:31:03.516962339 +0530 +--- mysql-test/suite/innodb/r/check_ibd_filesize.result ++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject @@ -3,18 +3,18 @@ # SPACE IN 5.7 THAN IN 5.6 # diff --git a/mysql-test/suite/innodb/r/gap_locks.result b/mysql-test/suite/innodb/r/gap_locks.result index cd60b1fab22..d98b71982c8 100644 --- a/mysql-test/suite/innodb/r/gap_locks.result +++ b/mysql-test/suite/innodb/r/gap_locks.result @@ -1,6 +1,6 @@ CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(40), c INT, INDEX(b,c)) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1,'1',1),(2,'2',1); +INSERT INTO t1 VALUES (1,'1',1),(2,'2',1),(3,'3',1); SET @save_locks= @@GLOBAL.innodb_status_output_locks; SET GLOBAL INNODB_STATUS_OUTPUT_LOCKS = 'ON'; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 6404a3812b3..150f950d591 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -204,7 +204,7 @@ CREATE INDEX c2d ON t1(c2); SHOW INDEX FROM t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored t1 0 PRIMARY 1 c1 A 80 NULL NULL BTREE NO -t1 1 c2d 1 c2 A 10 NULL NULL YES BTREE NO +t1 1 c2d 1 c2 A 5 NULL NULL YES BTREE NO EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range c2d c2d 5 NULL 32 Using where; Using index diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index a76837b91a2..1ebed058aaf 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -853,10 +853,10 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK explain select * from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 explain select * from t1 order by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 Using index +1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 drop table t1; SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET FOREIGN_KEY_CHECKS=0; diff --git a/mysql-test/suite/innodb/r/innodb-isolation.result b/mysql-test/suite/innodb/r/innodb-isolation.result index b6e512cc6de..8ff2c7f12e9 100644 --- a/mysql-test/suite/innodb/r/innodb-isolation.result +++ b/mysql-test/suite/innodb/r/innodb-isolation.result @@ -971,7 +971,7 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(*) FROM t1 WHERE c1 > (SELECT AVG(c1) FROM t1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where; Using index +1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where 2 SUBQUERY t1 index NULL k2 5 NULL # Using index # # Make all indexes in t2 obsolete to the active repeatable read transaction diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 742a822baa0..a4c1115bfd4 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -931,7 +931,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL # Using filesort explain select a from t1 order by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 4 NULL # Using index +1 SIMPLE t1 index NULL PRIMARY 4 NULL # explain select b from t1 order by b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL b 4 NULL # Using index @@ -1367,14 +1367,28 @@ PRIMARY KEY (`id`), KEY `id_version` (`id_version`) ) ENGINE=InnoDB; INSERT INTO t2 VALUES("3524", "1"),("3525", "1"),("1794", "4"),("102", "5"),("1822", "6"),("3382", "9"); +ANALYZE table t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 'description' +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +explain SELECT t2.id, t1.`label` FROM t2 INNER JOIN +(SELECT t1.id_object as id_object FROM t1 WHERE t1.`label` LIKE '%test%') AS lbl +ON (t2.id = lbl.id_object) INNER JOIN t1 ON (t2.id = t1.id_object); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL id_object NULL NULL NULL 6 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.id_object 1 +1 SIMPLE t1 ref id_object id_object 5 test.t1.id_object 1 SELECT t2.id, t1.`label` FROM t2 INNER JOIN (SELECT t1.id_object as id_object FROM t1 WHERE t1.`label` LIKE '%test%') AS lbl ON (t2.id = lbl.id_object) INNER JOIN t1 ON (t2.id = t1.id_object); id label -3382 Test 102 Le Pekin (Test) 1794 Test de resto 1822 Test 3 +3382 Test 3524 Societe Test 3525 Fournisseur Test drop table t1,t2; @@ -1676,7 +1690,7 @@ count(*) 0 explain select count(*) from t1 where x > -16; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 2 Using where; Using index +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 2 Using where select count(*) from t1 where x > -16; count(*) 2 diff --git a/mysql-test/suite/innodb/r/innodb_bug30423.result b/mysql-test/suite/innodb/r/innodb_bug30423.result index 786041370ef..8f66cedad4d 100644 --- a/mysql-test/suite/innodb/r/innodb_bug30423.result +++ b/mysql-test/suite/innodb/r/innodb_bug30423.result @@ -54,7 +54,7 @@ ON orgs.org_id=sa_opportunities.org_id LEFT JOIN bug30243_2 contacts ON orgs.org_id=contacts.org_id ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE orgs index NULL org_id 4 NULL ROWS Using index +1 SIMPLE orgs ALL NULL NULL NULL NULL ROWS 1 SIMPLE sa_opportunities ref org_id org_id 5 test.orgs.org_id ROWS Using index 1 SIMPLE contacts ref contacts$org_id contacts$org_id 5 test.orgs.org_id ROWS Using index select @@innodb_stats_method; @@ -83,7 +83,7 @@ ON orgs.org_id=sa_opportunities.org_id LEFT JOIN bug30243_2 contacts ON orgs.org_id=contacts.org_id; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE orgs index NULL org_id 4 NULL ROWS Using index +1 SIMPLE orgs ALL NULL NULL NULL NULL ROWS 1 SIMPLE sa_opportunities ref org_id org_id 5 test.orgs.org_id ROWS Using index 1 SIMPLE contacts ref contacts$org_id contacts$org_id 5 test.orgs.org_id ROWS Using index SELECT COUNT(*) FROM table_bug30423 WHERE org_id IS NULL; diff --git a/mysql-test/suite/innodb/r/innodb_bug30919.result b/mysql-test/suite/innodb/r/innodb_bug30919.result index 0062df3f470..42aa4ff302b 100644 --- a/mysql-test/suite/innodb/r/innodb_bug30919.result +++ b/mysql-test/suite/innodb/r/innodb_bug30919.result @@ -35,10 +35,6 @@ FROM test.part_tbl; -- debug to show the problem SET del_count = del_count - 2; END WHILE; END| -Warnings: -Level Warning -Code 1287 -Message ' INTO FROM...' instead CALL test.proc_part(); internal_count del_count 999 1000 diff --git a/mysql-test/suite/innodb/r/innodb_bug51920.result b/mysql-test/suite/innodb/r/innodb_bug51920.result index 9bc35174979..ddb9e29fab2 100644 --- a/mysql-test/suite/innodb/r/innodb_bug51920.result +++ b/mysql-test/suite/innodb/r/innodb_bug51920.result @@ -11,8 +11,6 @@ connection default; SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO="UPDATE bug51920 SET i=2" INTO @thread_id; -Warnings: -Warning 1287 ' INTO FROM...' instead KILL @thread_id; connection con1; Got one of the listed errors diff --git a/mysql-test/suite/innodb/r/innodb_bug57252.result b/mysql-test/suite/innodb/r/innodb_bug57252.result index 66183c2c42d..18e47900e41 100644 --- a/mysql-test/suite/innodb/r/innodb_bug57252.result +++ b/mysql-test/suite/innodb/r/innodb_bug57252.result @@ -1,5 +1,5 @@ cardinality -2 +1 Table Op Msg_type Msg_text test.bug57252 analyze status Engine-independent statistics collected test.bug57252 analyze status OK diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index aa8cc118ce6..7d5dc38f52c 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -191,8 +191,8 @@ min(7) 7 explain select min(7) from t2i join t1i; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1i ALL NULL NULL NULL NULL 0 -1 SIMPLE t2i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) +1 SIMPLE t2i ALL NULL NULL NULL NULL 1 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) select min(7) from t2i join t1i; min(7) NULL @@ -207,8 +207,8 @@ max(7) 7 explain select max(7) from t2i join t1i; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1i ALL NULL NULL NULL NULL 0 -1 SIMPLE t2i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) +1 SIMPLE t2i ALL NULL NULL NULL NULL 1 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) select max(7) from t2i join t1i; max(7) NULL @@ -239,7 +239,7 @@ select 1, max(1) from t1i where 1=99; explain select count(*), min(7), max(7) from t1m, t1i; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1m system NULL NULL NULL NULL 0 Const row not found -1 SIMPLE t1i ALL NULL NULL NULL NULL 0 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 select count(*), min(7), max(7) from t1m, t1i; count(*) min(7) max(7) 0 NULL NULL @@ -253,7 +253,7 @@ count(*) min(7) max(7) explain select count(*), min(7), max(7) from t2m, t1i; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2m system NULL NULL NULL NULL 1 -1 SIMPLE t1i ALL NULL NULL NULL NULL 0 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 select count(*), min(7), max(7) from t2m, t1i; count(*) min(7) max(7) 0 NULL NULL @@ -346,10 +346,10 @@ insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d"); alter table t1 drop primary key, add primary key (f2, f1); explain select distinct f1 a, f1 b from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary explain select distinct f1, f2 from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 drop table t1; CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), INDEX (name)); @@ -396,7 +396,7 @@ test.t1 analyze status OK flush tables; EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref name name 22 const 2 Using where; Using index +1 SIMPLE t1 range name name 44 NULL 2 Using where; Using index for group-by SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5'; name dept rs5 cs10 @@ -405,7 +405,7 @@ DELETE FROM t1; # Masking (#) number in "rows" column of the following EXPLAIN output, as it may vary (bug#47746). EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref name name 22 const # Using where; Using index +1 SIMPLE t1 range name name 44 NULL # Using where; Using index for group-by SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5'; name dept DROP TABLE t1; @@ -1193,7 +1193,7 @@ INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20), 1 FROM t1; INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20), 1 FROM t1; EXPLAIN SELECT b, SUM(c) FROM t1 GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL b 5 NULL 128 +1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using temporary; Using filesort EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort @@ -1312,13 +1312,13 @@ EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; id 1 select_type SIMPLE table t1 -type range +type index possible_keys bkey -key bkey -key_len 5 +key PRIMARY +key_len 4 ref NULL rows 32 -Extra Using where; Using index; Using filesort +Extra Using where SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; a b 1 2 @@ -1407,13 +1407,13 @@ EXPLAIN SELECT * FROM t2 WHERE b=1 ORDER BY a; id 1 select_type SIMPLE table t2 -type ref +type index possible_keys bkey -key bkey -key_len 5 -ref const +key PRIMARY +key_len 4 +ref NULL rows 16 -Extra Using where; Using index; Using filesort +Extra Using where SELECT * FROM t2 WHERE b=1 ORDER BY a; a b c 1 1 1 @@ -1629,7 +1629,7 @@ c b d 3 2 40 EXPLAIN SELECT c,b FROM t1 GROUP BY c,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL c 8 NULL 3 Using index +1 SIMPLE t1 index NULL c 8 NULL 3 SELECT c,b FROM t1 GROUP BY c,b; c b 1 1 @@ -1787,7 +1787,7 @@ INSERT INTO t1 VALUES (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL idx NULL NULL NULL 4 Using where; Using filesort +1 SIMPLE t1 ref_or_null idx idx 5 const 3 Using index condition; Using filesort SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; id type d 191 member 1 @@ -1797,13 +1797,16 @@ DROP TABLE t1; set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; set global innodb_autoextend_increment=8; set global innodb_autoextend_increment=@my_innodb_autoextend_increment; +# +# Bug #37830: ORDER BY ASC/DESC - no difference +# CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b)) ENGINE=InnoDB; -INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1); +INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1), (100,2,2); INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1; EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range t1_b t1_b 5 NULL 8 Using where +1 SIMPLE t1 ref t1_b t1_b 5 const 8 Using where SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; a b c 8 1 1 @@ -2342,24 +2345,24 @@ EXPLAIN SELECT c FROM bar WHERE b>2;; id 1 select_type SIMPLE table bar -type ALL +type range possible_keys b -key NULL -key_len NULL +key b +key_len 5 ref NULL -rows 6 -Extra Using where +rows 5 +Extra Using index condition EXPLAIN SELECT c FROM foo WHERE b>2;; id 1 select_type SIMPLE table foo -type ALL +type range possible_keys b -key NULL -key_len NULL +key b +key_len 5 ref NULL -rows 6 -Extra Using where +rows 5 +Extra Using index condition EXPLAIN SELECT c FROM foo2 WHERE b>2;; id 1 select_type SIMPLE @@ -2970,7 +2973,7 @@ NULL 75 EXPLAIN SELECT t1.id,t2.id FROM t2 LEFT JOIN t1 ON t1.id>=74 AND t1.id<=0 WHERE t2.id=75 AND t1.id IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 const PRIMARY NULL NULL NULL 1 Impossible ON condition +1 SIMPLE t1 const PRIMARY NULL NULL NULL 0 Impossible ON condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where DROP TABLE t1,t2; # @@ -3066,7 +3069,7 @@ f1 f2 f3 f4 EXPLAIN SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE ORDER BY f1 DESC LIMIT 5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range f2,f4 f4 1 NULL 22 Using where +1 SIMPLE t1 index f2,f4 PRIMARY 4 NULL 5 Using where DROP TABLE t1; # # Bug#54117 crash in thr_multi_unlock, temporary table @@ -3114,8 +3117,8 @@ select_type SIMPLE table t1 type index possible_keys NULL -key PRIMARY -key_len 8 +key b +key_len 13 ref NULL rows 3 Extra Using index @@ -3127,8 +3130,8 @@ select_type SIMPLE table t1 type index possible_keys NULL -key PRIMARY -key_len 8 +key b +key_len 18 ref NULL rows 3 Extra Using index @@ -3291,7 +3294,7 @@ SELECT t2.b FROM t1,t2 WHERE t1.a IN (SELECT 1 FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -1 PRIMARY t2 index NULL PRIMARY 4 NULL 1 Using index; FirstMatch(t1); Using join buffer (incremental, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 FirstMatch(t1); Using join buffer (incremental, BNL join) SELECT t2.b FROM t1,t2 WHERE t1.a IN (SELECT 1 FROM t2); b 1 diff --git a/mysql-test/suite/innodb/r/innodb_stats.result b/mysql-test/suite/innodb/r/innodb_stats.result index b300af767c6..cb5247f081e 100644 --- a/mysql-test/suite/innodb/r/innodb_stats.result +++ b/mysql-test/suite/innodb/r/innodb_stats.result @@ -151,7 +151,7 @@ INDEX_NAME a_key SEQ_IN_INDEX 1 COLUMN_NAME a COLLATION A -CARDINALITY 2 +CARDINALITY 1 SUB_PART NULL PACKED NULL NULLABLE YES @@ -204,7 +204,7 @@ INDEX_NAME a_key SEQ_IN_INDEX 1 COLUMN_NAME a COLLATION A -CARDINALITY 3 +CARDINALITY 1 SUB_PART NULL PACKED NULL NULLABLE YES @@ -257,7 +257,7 @@ INDEX_NAME a_key SEQ_IN_INDEX 1 COLUMN_NAME a COLLATION A -CARDINALITY 2 +CARDINALITY 1 SUB_PART NULL PACKED NULL NULLABLE YES @@ -522,7 +522,7 @@ INDEX_NAME a_key SEQ_IN_INDEX 1 COLUMN_NAME a COLLATION A -CARDINALITY 10 +CARDINALITY 5 SUB_PART NULL PACKED NULL NULLABLE YES diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch.result b/mysql-test/suite/innodb/r/innodb_stats_fetch.result index d7b7d78ec71..6df1831db48 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch.result @@ -131,16 +131,16 @@ FROM information_schema.statistics WHERE table_name = 'test_ps_fetch' ORDER BY index_name, seq_in_index; seq_in_index 1 column_name c -cardinality 6 +cardinality 3 seq_in_index 2 column_name d -cardinality 22 +cardinality 11 seq_in_index 1 column_name a -cardinality 40 +cardinality 20 seq_in_index 2 column_name b -cardinality 200 +cardinality 90 SELECT table_rows, avg_row_length, max_data_length, index_length FROM information_schema.tables WHERE table_name = 'test_ps_fetch'; diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result b/mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result index 1f8471304d5..b1e6bb7fa72 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch_corrupted.result @@ -24,7 +24,7 @@ FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_corrupted' ORDER BY index_name, seq_in_index; seq_in_index 1 column_name a -cardinality 0 +cardinality 1 SELECT table_rows, avg_row_length, max_data_length, index_length FROM information_schema.tables WHERE table_name = 'test_ps_fetch_corrupted'; table_rows 0 @@ -38,7 +38,7 @@ FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_corrupted' ORDER BY index_name, seq_in_index; seq_in_index 1 column_name a -cardinality 0 +cardinality 1 SELECT table_rows, avg_row_length, max_data_length, index_length FROM information_schema.tables WHERE table_name = 'test_ps_fetch_corrupted'; table_rows 0 diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result b/mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result index 91bb2bf3ecd..a6627417d1a 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch_nonexistent.result @@ -22,7 +22,7 @@ FROM information_schema.statistics WHERE table_name = 'test_ps_fetch_nonexistent ORDER BY index_name, seq_in_index; seq_in_index 1 column_name a -cardinality 0 +cardinality 1 SELECT table_rows, avg_row_length, max_data_length, index_length FROM information_schema.tables WHERE table_name = 'test_ps_fetch_nonexistent'; table_rows 0 diff --git a/mysql-test/suite/innodb/r/instant_alter_limit,16k.rdiff b/mysql-test/suite/innodb/r/instant_alter_limit,16k.rdiff index 57d87f7172f..320df318434 100644 --- a/mysql-test/suite/innodb/r/instant_alter_limit,16k.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_limit,16k.rdiff @@ -1,5 +1,5 @@ ---- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530 -+++ instant_alter_limit,16k.reject 2020-05-26 20:14:38.452463919 +0530 +--- instant_alter_limit.result ++++ instant_alter_limit,16k.reject @@ -45,3 +45,10 @@ instants 502 diff --git a/mysql-test/suite/innodb/r/instant_alter_limit,32k.rdiff b/mysql-test/suite/innodb/r/instant_alter_limit,32k.rdiff index 8f8cf64b7fc..951f0ce2320 100644 --- a/mysql-test/suite/innodb/r/instant_alter_limit,32k.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_limit,32k.rdiff @@ -1,5 +1,5 @@ ---- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530 -+++ instant_alter_limit,32k.reject 2020-05-26 19:59:19.743877366 +0530 +--- instant_alter_limit.result ++++ instant_alter_limit,32k.reject @@ -43,5 +43,12 @@ FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; diff --git a/mysql-test/suite/innodb/r/instant_alter_limit,4k.rdiff b/mysql-test/suite/innodb/r/instant_alter_limit,4k.rdiff index dad28218a02..0ebd590ad54 100644 --- a/mysql-test/suite/innodb/r/instant_alter_limit,4k.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_limit,4k.rdiff @@ -1,5 +1,5 @@ ---- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530 -+++ instant_alter_limit,4k.reject 2020-05-26 20:17:53.314736548 +0530 +--- instant_alter_limit.result ++++ instant_alter_limit,4k.reject @@ -5,6 +5,276 @@ ENGINE=InnoDB; INSERT INTO t VALUES(1,2,3,4,5); diff --git a/mysql-test/suite/innodb/r/instant_alter_limit,64k.rdiff b/mysql-test/suite/innodb/r/instant_alter_limit,64k.rdiff index d7479dbba40..7c58fa4a8db 100644 --- a/mysql-test/suite/innodb/r/instant_alter_limit,64k.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_limit,64k.rdiff @@ -1,5 +1,5 @@ ---- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530 -+++ instant_alter_limit,64k.reject 2020-05-26 20:00:22.499711222 +0530 +--- instant_alter_limit.result ++++ instant_alter_limit,64k.reject @@ -43,5 +43,12 @@ FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; diff --git a/mysql-test/suite/innodb/r/instant_alter_limit,8k.rdiff b/mysql-test/suite/innodb/r/instant_alter_limit,8k.rdiff index 1fe3e1a56eb..d70156f3083 100644 --- a/mysql-test/suite/innodb/r/instant_alter_limit,8k.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_limit,8k.rdiff @@ -1,5 +1,5 @@ ---- instant_alter_limit.result 2020-05-26 18:01:27.377946439 +0530 -+++ instant_alter_limit,8k.reject 2020-05-26 20:19:50.881869095 +0530 +--- instant_alter_limit.result ++++ instant_alter_limit,8k.reject @@ -5,6 +5,28 @@ ENGINE=InnoDB; INSERT INTO t VALUES(1,2,3,4,5); diff --git a/mysql-test/suite/innodb/r/max_record_size,16k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,16k,compact,innodb.rdiff index 118145bec2e..b9f51624729 100644 --- a/mysql-test/suite/innodb/r/max_record_size,16k,compact,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,16k,compact,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:51:26.070418078 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,65 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,16k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,16k,dynamic,innodb.rdiff index 33067866b82..5effc664f2c 100644 --- a/mysql-test/suite/innodb/r/max_record_size,16k,dynamic,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,16k,dynamic,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:52:54.580956978 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,207 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,16k,innodb,redundant.rdiff b/mysql-test/suite/innodb/r/max_record_size,16k,innodb,redundant.rdiff index e50e4d2be3a..227b64a8a48 100644 --- a/mysql-test/suite/innodb/r/max_record_size,16k,innodb,redundant.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,16k,innodb,redundant.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:55:05.258762945 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,65 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,32k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,32k,compact,innodb.rdiff index 1bc03a5d97a..d236e12b1e1 100644 --- a/mysql-test/suite/innodb/r/max_record_size,32k,compact,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,32k,compact,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:27:08.004932026 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,104 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,32k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,32k,dynamic,innodb.rdiff index 71c4c2e41b7..ce9462b6900 100644 --- a/mysql-test/suite/innodb/r/max_record_size,32k,dynamic,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,32k,dynamic,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:38:41.609328820 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,351 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,32k,innodb,redundant.rdiff b/mysql-test/suite/innodb/r/max_record_size,32k,innodb,redundant.rdiff index e42b3de8845..53d6f76a2d2 100644 --- a/mysql-test/suite/innodb/r/max_record_size,32k,innodb,redundant.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,32k,innodb,redundant.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:41:03.319664978 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,104 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,4k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,4k,compact,innodb.rdiff index 6f08dab3ca1..37871798f31 100644 --- a/mysql-test/suite/innodb/r/max_record_size,4k,compact,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,4k,compact,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:56:23.489432164 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -1,47 +1,37 @@ call mtr.add_suppression("Cannot add field `.*` in table `test`.`t1` because after adding it, the row size is"); CREATE TABLE t1 ( diff --git a/mysql-test/suite/innodb/r/max_record_size,4k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,4k,dynamic,innodb.rdiff index bd37d4354e7..b0b6b007d97 100644 --- a/mysql-test/suite/innodb/r/max_record_size,4k,dynamic,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,4k,dynamic,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:57:38.636143710 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -1,47 +1,103 @@ call mtr.add_suppression("Cannot add field `.*` in table `test`.`t1` because after adding it, the row size is"); CREATE TABLE t1 ( diff --git a/mysql-test/suite/innodb/r/max_record_size,4k,innodb,redundant.rdiff b/mysql-test/suite/innodb/r/max_record_size,4k,innodb,redundant.rdiff index 93c39ff6714..0db6450d9c1 100644 --- a/mysql-test/suite/innodb/r/max_record_size,4k,innodb,redundant.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,4k,innodb,redundant.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:58:58.318768169 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -1,47 +1,37 @@ call mtr.add_suppression("Cannot add field `.*` in table `test`.`t1` because after adding it, the row size is"); CREATE TABLE t1 ( diff --git a/mysql-test/suite/innodb/r/max_record_size,64k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,64k,compact,innodb.rdiff index 5e6c62212d1..ab75975e238 100644 --- a/mysql-test/suite/innodb/r/max_record_size,64k,compact,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,64k,compact,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:45:21.760116841 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,186 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,64k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,64k,dynamic,innodb.rdiff index 2cbf4cd9c54..3e13a510055 100644 --- a/mysql-test/suite/innodb/r/max_record_size,64k,dynamic,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,64k,dynamic,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:48:32.453208310 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,486 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,64k,innodb,redundant.rdiff b/mysql-test/suite/innodb/r/max_record_size,64k,innodb,redundant.rdiff index c324969fb21..a31285a2714 100644 --- a/mysql-test/suite/innodb/r/max_record_size,64k,innodb,redundant.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,64k,innodb,redundant.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 12:50:05.663724193 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -3,45 +3,104 @@ c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255), c6 CHAR(255), c7 CHAR(255), c8 CHAR(255), diff --git a/mysql-test/suite/innodb/r/max_record_size,8k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,8k,compact,innodb.rdiff index 4db669a8aa6..cafb5f25a0d 100644 --- a/mysql-test/suite/innodb/r/max_record_size,8k,compact,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,8k,compact,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 13:00:25.037261867 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -12,7 +12,7 @@ c9 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255), c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255) diff --git a/mysql-test/suite/innodb/r/max_record_size,8k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,8k,dynamic,innodb.rdiff index 5f79d77e7f9..2f592fbb4b3 100644 --- a/mysql-test/suite/innodb/r/max_record_size,8k,dynamic,innodb.rdiff +++ b/mysql-test/suite/innodb/r/max_record_size,8k,dynamic,innodb.rdiff @@ -1,5 +1,5 @@ ---- max_record_size.result 2019-07-03 11:54:44.591421526 +0300 -+++ max_record_size.reject 2019-07-03 13:01:51.215756779 +0300 +--- max_record_size.result ++++ max_record_size.reject @@ -12,7 +12,7 @@ c9 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255), c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255) diff --git a/mysql-test/suite/innodb/r/mdev-14846.result b/mysql-test/suite/innodb/r/mdev-14846.result index 219bd718feb..b41f6e6bf97 100644 --- a/mysql-test/suite/innodb/r/mdev-14846.result +++ b/mysql-test/suite/innodb/r/mdev-14846.result @@ -33,13 +33,25 @@ pk f1 f2 f3 SET DEBUG_SYNC='now SIGNAL default_dml'; connection default; SET DEBUG_SYNC='now WAIT_FOR default_dml'; -UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h'; +explain UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 IGNORE INDEX (f1) WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h'; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY alias1 ALL NULL NULL NULL NULL # +1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL # Using where +UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 IGNORE INDEX (f1) WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h'; connect con2,localhost,root,,test; set debug_sync='now WAIT_FOR default_dml'; SET DEBUG_SYNC='now SIGNAL con1_dml2'; disconnect con2; connection con1; SET DEBUG_SYNC='now WAIT_FOR con1_dml2'; +explain UPDATE v4, t1 SET t1.pk = 76 WHERE t1.f2 IN ( SELECT t2.f FROM t2 INNER JOIN t3 ); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL f1 12 NULL # Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL # +1 PRIMARY eq_ref distinct_key distinct_key 13 func # +2 MATERIALIZED t3 ALL NULL NULL NULL NULL # +2 MATERIALIZED t2 ALL NULL NULL NULL NULL # UPDATE v4, t1 SET t1.pk = 76 WHERE t1.f2 IN ( SELECT t2.f FROM t2 INNER JOIN t3 ); connection default; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction diff --git a/mysql-test/suite/innodb/r/partition_locking.result b/mysql-test/suite/innodb/r/partition_locking.result index f25b8a15a24..b5e96f965b3 100644 --- a/mysql-test/suite/innodb/r/partition_locking.result +++ b/mysql-test/suite/innodb/r/partition_locking.result @@ -148,7 +148,7 @@ a b c d e 03 03 343 7 03_03_343 03 06 343 8 03_06_343 03 07 343 9 03_07_343 -SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a LOCK IN SHARE MODE SKIP LOCKED; +SELECT a,count(b) FROM t1 force index (a) GROUP BY a ORDER BY a LOCK IN SHARE MODE SKIP LOCKED; a count(b) 01 5 03 3 diff --git a/mysql-test/suite/innodb/r/restart,16k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,16k,innodb.rdiff index b36ed067913..3149b9aeab0 100644 --- a/mysql-test/suite/innodb/r/restart,16k,innodb.rdiff +++ b/mysql-test/suite/innodb/r/restart,16k,innodb.rdiff @@ -1,5 +1,5 @@ ---- ./suite/innodb/r/restart.result 2022-01-18 20:36:56.054653376 +1100 -+++ suite/innodb/r/restart.reject 2022-01-19 08:12:28.602794678 +1100 +--- ./suite/innodb/r/restart.result ++++ suite/innodb/r/restart.reject @@ -32,10 +32,10 @@ SELECT @@innodb_buffer_pool_size INTO @innodb_buffer_pool_size_orig; SELECT CEILING((256 + 64) * @@innodb_page_size / 1048576) * 1048576 INTO @min_pool_size; diff --git a/mysql-test/suite/innodb/r/restart,32k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,32k,innodb.rdiff index 8fa057814c4..3f00646cb37 100644 --- a/mysql-test/suite/innodb/r/restart,32k,innodb.rdiff +++ b/mysql-test/suite/innodb/r/restart,32k,innodb.rdiff @@ -1,5 +1,5 @@ ---- ./suite/innodb/r/restart.result 2022-01-18 20:36:56.054653376 +1100 -+++ suite/innodb/r/restart.reject 2022-01-19 08:07:57.402230887 +1100 +--- ./suite/innodb/r/restart.result ++++ suite/innodb/r/restart.reject @@ -32,10 +32,10 @@ SELECT @@innodb_buffer_pool_size INTO @innodb_buffer_pool_size_orig; SELECT CEILING((256 + 64) * @@innodb_page_size / 1048576) * 1048576 INTO @min_pool_size; diff --git a/mysql-test/suite/innodb/r/restart,4k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,4k,innodb.rdiff index 7d0846360e0..b00c56ef81f 100644 --- a/mysql-test/suite/innodb/r/restart,4k,innodb.rdiff +++ b/mysql-test/suite/innodb/r/restart,4k,innodb.rdiff @@ -1,5 +1,5 @@ ---- ./suite/innodb/r/restart.result 2022-01-18 20:36:56.054653376 +1100 -+++ suite/innodb/r/restart.reject 2022-01-19 08:13:56.397475513 +1100 +--- ./suite/innodb/r/restart.result ++++ suite/innodb/r/restart.reject @@ -32,10 +32,10 @@ SELECT @@innodb_buffer_pool_size INTO @innodb_buffer_pool_size_orig; SELECT CEILING((256 + 64) * @@innodb_page_size / 1048576) * 1048576 INTO @min_pool_size; diff --git a/mysql-test/suite/innodb/r/restart,64k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,64k,innodb.rdiff index 3ac9f45b196..886cbcde7d9 100644 --- a/mysql-test/suite/innodb/r/restart,64k,innodb.rdiff +++ b/mysql-test/suite/innodb/r/restart,64k,innodb.rdiff @@ -1,5 +1,5 @@ ---- ./suite/innodb/r/restart.result 2022-01-18 20:36:56.054653376 +1100 -+++ suite/innodb/r/restart.reject 2022-01-19 08:11:32.418759095 +1100 +--- ./suite/innodb/r/restart.result ++++ suite/innodb/r/restart.reject @@ -32,10 +32,10 @@ SELECT @@innodb_buffer_pool_size INTO @innodb_buffer_pool_size_orig; SELECT CEILING((256 + 64) * @@innodb_page_size / 1048576) * 1048576 INTO @min_pool_size; diff --git a/mysql-test/suite/innodb/r/restart,8k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,8k,innodb.rdiff index 4da55ebfcef..40a9e1bad1c 100644 --- a/mysql-test/suite/innodb/r/restart,8k,innodb.rdiff +++ b/mysql-test/suite/innodb/r/restart,8k,innodb.rdiff @@ -1,5 +1,5 @@ ---- ./suite/innodb/r/restart.result 2022-01-18 20:36:56.054653376 +1100 -+++ suite/innodb/r/restart.reject 2022-01-19 08:13:11.027788852 +1100 +--- ./suite/innodb/r/restart.result ++++ suite/innodb/r/restart.reject @@ -32,10 +32,10 @@ SELECT @@innodb_buffer_pool_size INTO @innodb_buffer_pool_size_orig; SELECT CEILING((256 + 64) * @@innodb_page_size / 1048576) * 1048576 INTO @min_pool_size; diff --git a/mysql-test/suite/innodb/r/table_index_statistics.result b/mysql-test/suite/innodb/r/table_index_statistics.result index 286c5f9325f..ddb23afd346 100644 --- a/mysql-test/suite/innodb/r/table_index_statistics.result +++ b/mysql-test/suite/innodb/r/table_index_statistics.result @@ -14,13 +14,11 @@ ROWS_READ 10 SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; ROWS_READ -10 FLUSH TABLE_STATISTICS; SELECT ROWS_READ FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t1'; ROWS_READ SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; ROWS_READ -10 FLUSH INDEX_STATISTICS; SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; ROWS_READ @@ -32,7 +30,6 @@ ROWS_READ 10 SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; ROWS_READ -10 DROP TABLE t1; CREATE TABLE t2 (c1 INT UNSIGNED); ALTER TABLE t2 MODIFY c1 FLOAT; diff --git a/mysql-test/suite/innodb/t/gap_locks.test b/mysql-test/suite/innodb/t/gap_locks.test index 77ce2c842b1..575a966ec42 100644 --- a/mysql-test/suite/innodb/t/gap_locks.test +++ b/mysql-test/suite/innodb/t/gap_locks.test @@ -2,7 +2,7 @@ CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(40), c INT, INDEX(b,c)) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1,'1',1),(2,'2',1); +INSERT INTO t1 VALUES (1,'1',1),(2,'2',1),(3,'3',1); SET @save_locks= @@GLOBAL.innodb_status_output_locks; SET GLOBAL INNODB_STATUS_OUTPUT_LOCKS = 'ON'; diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index 58e9899bd40..9211a51dcfc 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -1106,7 +1106,13 @@ CREATE TABLE t2 ( ) ENGINE=InnoDB; INSERT INTO t2 VALUES("3524", "1"),("3525", "1"),("1794", "4"),("102", "5"),("1822", "6"),("3382", "9"); +# We have to analyze the tables to make the row count stable +ANALYZE table t1,t2; +explain SELECT t2.id, t1.`label` FROM t2 INNER JOIN +(SELECT t1.id_object as id_object FROM t1 WHERE t1.`label` LIKE '%test%') AS lbl +ON (t2.id = lbl.id_object) INNER JOIN t1 ON (t2.id = t1.id_object); +--sorted_result SELECT t2.id, t1.`label` FROM t2 INNER JOIN (SELECT t1.id_object as id_object FROM t1 WHERE t1.`label` LIKE '%test%') AS lbl ON (t2.id = lbl.id_object) INNER JOIN t1 ON (t2.id = t1.id_object); diff --git a/mysql-test/suite/innodb/t/mdev-14846.test b/mysql-test/suite/innodb/t/mdev-14846.test index adcefecd52f..079a066cec5 100644 --- a/mysql-test/suite/innodb/t/mdev-14846.test +++ b/mysql-test/suite/innodb/t/mdev-14846.test @@ -38,7 +38,9 @@ SET DEBUG_SYNC='now SIGNAL default_dml'; --connection default SET DEBUG_SYNC='now WAIT_FOR default_dml'; ---send UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h' +--replace_column 9 # +explain UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 IGNORE INDEX (f1) WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h'; +--send UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 IGNORE INDEX (f1) WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h' # It holds the lock of all record in t3 and tries to acquire record lock for the table t1. --connect (con2,localhost,root,,test) @@ -52,6 +54,8 @@ disconnect con2; # Cleanup --connection con1 SET DEBUG_SYNC='now WAIT_FOR con1_dml2'; +--replace_column 9 # +explain UPDATE v4, t1 SET t1.pk = 76 WHERE t1.f2 IN ( SELECT t2.f FROM t2 INNER JOIN t3 ); UPDATE v4, t1 SET t1.pk = 76 WHERE t1.f2 IN ( SELECT t2.f FROM t2 INNER JOIN t3 ); # It holds the record lock on table t1 and tries to acquire record lock on t3. # leads to deadlock (con1 trx is waiting for default trx and vice versa) diff --git a/mysql-test/suite/innodb/t/partition_locking.test b/mysql-test/suite/innodb/t/partition_locking.test index 13457c1d9be..c4e6bff9bbb 100644 --- a/mysql-test/suite/innodb/t/partition_locking.test +++ b/mysql-test/suite/innodb/t/partition_locking.test @@ -104,7 +104,7 @@ SELECT * FROM t1 LOCK IN SHARE MODE; --error ER_LOCK_WAIT_TIMEOUT SELECT * FROM t1 LOCK IN SHARE MODE NOWAIT; SELECT * FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; -SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a LOCK IN SHARE MODE SKIP LOCKED; +SELECT a,count(b) FROM t1 force index (a) GROUP BY a ORDER BY a LOCK IN SHARE MODE SKIP LOCKED; SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; SELECT d,a,b,c FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index cb615069067..2a6fb81f4bb 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -537,6 +537,9 @@ CREATE TABLE t2 (a int, b2 char(10), FULLTEXT KEY b2 (b2)) ENGINE = InnoDB; INSERT INTO t2 VALUES (1,'Scargill'); CREATE TABLE t3 (a int, b int) ENGINE = InnoDB; INSERT INTO t3 VALUES (1,1), (2,1); +SELECT * FROM t2 where MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE); +a b2 +1 Scargill # t2 should use full text index EXPLAIN SELECT count(*) FROM t1 WHERE @@ -546,8 +549,8 @@ WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE) ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 MATERIALIZED t2 fulltext b2 b2 0 1 Using where -2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 fulltext b2 b2 0 1 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where # should return 0 SELECT count(*) FROM t1 WHERE not exists( diff --git a/mysql-test/suite/innodb_fts/r/fulltext_misc.result b/mysql-test/suite/innodb_fts/r/fulltext_misc.result index c58cf5ba62c..f6087a01422 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext_misc.result +++ b/mysql-test/suite/innodb_fts/r/fulltext_misc.result @@ -8,9 +8,9 @@ EXPLAIN SELECT 1 FROM t1 WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a ON (MATCH(t1.f1) AGAINST ("")) WHERE t1.f1 GROUP BY t1.f1)); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL f1_2 8 NULL 1 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where -2 SUBQUERY a index NULL f1_2 8 NULL 1 Using index +2 SUBQUERY a ALL NULL NULL NULL NULL 1 PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE 1 > ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a @@ -18,14 +18,14 @@ PREPARE stmt FROM WHERE t1.f1 GROUP BY t1.f1))'; EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL f1_2 8 NULL 1 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where -2 SUBQUERY a index NULL f1_2 8 NULL 1 Using index +2 SUBQUERY a ALL NULL NULL NULL NULL 1 EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL f1_2 8 NULL 1 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where -2 SUBQUERY a index NULL f1_2 8 NULL 1 Using index +2 SUBQUERY a ALL NULL NULL NULL NULL 1 DEALLOCATE PREPARE stmt; PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 @@ -34,14 +34,14 @@ PREPARE stmt FROM WHERE t1.f1 GROUP BY t1.f1))'; EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL f1_2 8 NULL 1 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where -2 SUBQUERY a index NULL f1_2 8 NULL 1 Using index +2 SUBQUERY a ALL NULL NULL NULL NULL 1 EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL f1_2 8 NULL 1 Using index +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where -2 SUBQUERY a index NULL f1_2 8 NULL 1 Using index +2 SUBQUERY a ALL NULL NULL NULL NULL 1 DEALLOCATE PREPARE stmt; DROP TABLE t1; drop table if exists t1; diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test index 3ddc1856b7f..d9bf14cbe6b 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext.test +++ b/mysql-test/suite/innodb_fts/t/fulltext.test @@ -570,6 +570,8 @@ INSERT INTO t2 VALUES (1,'Scargill'); CREATE TABLE t3 (a int, b int) ENGINE = InnoDB; INSERT INTO t3 VALUES (1,1), (2,1); +SELECT * FROM t2 where MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE); + --echo # t2 should use full text index EXPLAIN SELECT count(*) FROM t1 WHERE diff --git a/mysql-test/suite/innodb_gis/r/create_spatial_index.result b/mysql-test/suite/innodb_gis/r/create_spatial_index.result index d3c69294c10..30b41b41e62 100644 --- a/mysql-test/suite/innodb_gis/r/create_spatial_index.result +++ b/mysql-test/suite/innodb_gis/r/create_spatial_index.result @@ -57,10 +57,14 @@ ANALYZE TABLE tab; Table Op Msg_type Msg_text test.tab analyze status Engine-independent statistics collected test.tab analyze status OK +# Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); -EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; +EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1+0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) @@ -74,7 +78,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 300 300,400 400)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 4 POLYGON((300 300,400 400,500 500,300 500,300 400,300 300)) @@ -85,10 +89,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRContains(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRWithin SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -99,10 +104,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the ST_Crosses SET @g1 = ST_GeomFromText('POLYGON((100 200,200 300,400 500,500 300,300 200,100 300,100 200))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 4 POLYGON((300 300,400 400,500 500,300 500,300 400,300 300)) @@ -116,7 +122,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 10 10,30 30,40 40)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_CRosses(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -127,6 +133,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE ST_Crosses(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -145,14 +152,15 @@ c1 ST_Astext(c4) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where +# Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 10 POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010)) @@ -166,7 +174,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -182,7 +190,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 30 30,40 40,50 50)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -194,10 +202,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the Overelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) @@ -218,14 +227,15 @@ c1 ST_Astext(c4) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 8 Using where EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 8 Using where +# Test the ST_Touches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 2 POLYGON((40 50,40 70,50 100,70 100,80 80,70 50,40 50)) @@ -239,7 +249,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 100 100,200 200,300 300)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 4 POLYGON((300 300,400 400,500 500,300 500,300 400,300 300)) @@ -250,10 +260,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE ST_Touches(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) @@ -267,7 +278,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -278,6 +289,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -296,14 +308,15 @@ c1 ST_Astext(c4) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where +# Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 10 POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010)) @@ -314,10 +327,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -333,7 +347,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 30 30,40 40,50 50)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -345,10 +359,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBROverelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) @@ -359,10 +374,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRTouches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRTouches(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRTouches(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 2 POLYGON((40 50,40 70,50 100,70 100,80 80,70 50,40 50)) @@ -373,6 +389,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRTouches(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where +# Test with Procedure CREATE PROCEDURE proc_wl6968() BEGIN SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); @@ -383,11 +400,12 @@ EXPLAIN DELETE FROM tab WHERE MBRContains(tab.c4, @g1); END | CALL proc_wl6968(); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the Delete & Update SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) @@ -486,6 +504,7 @@ ANALYZE TABLE tab; Table Op Msg_type Msg_text test.tab analyze status Engine-independent statistics collected test.tab analyze status OK +# Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -514,6 +533,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRContains(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRWithin SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -528,6 +548,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the ST_Crosses SET @g1 = ST_GeomFromText('POLYGON((100 200,200 300,400 500,500 300,300 200,100 300,100 200))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -556,10 +577,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE ST_Crosses(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where; Using filesort +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where; Using filesort SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -574,10 +596,11 @@ c1 ST_Astext(c4) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where +# Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -592,6 +615,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -623,6 +647,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the Overelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -640,17 +665,18 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING(7 1,30 30,1010 3010,1010 2010,3010 3010,4010 4010,5010 5010 )'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where; Using filesort +1 SIMPLE tab range idx3 idx3 34 NULL 8 Using where; Using filesort SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 8 Using where EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 8 Using where +# Test the ST_Touches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -679,6 +705,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE ST_Touches(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -707,10 +734,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where; Using filesort +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where; Using filesort SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -725,10 +753,11 @@ c1 ST_Astext(c4) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where +# Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -743,6 +772,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -774,6 +804,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBROverelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -788,6 +819,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRTouches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRTouches(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -802,6 +834,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRTouches(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where +# Test with Procedure CREATE PROCEDURE proc_wl6968() BEGIN SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); @@ -817,6 +850,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the Delete & Update SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) @@ -904,10 +938,11 @@ ANALYZE TABLE tab; Table Op Msg_type Msg_text test.tab analyze status Engine-independent statistics collected test.tab analyze status OK +# Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) @@ -921,7 +956,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 300 300,400 400)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 4 POLYGON((300 300,400 400,500 500,300 500,300 400,300 300)) @@ -932,10 +967,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRContains(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRWithin SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -946,10 +982,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the ST_Crosses SET @g1 = ST_GeomFromText('POLYGON((100 200,200 300,400 500,500 300,300 200,100 300,100 200))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 4 POLYGON((300 300,400 400,500 500,300 500,300 400,300 300)) @@ -963,7 +1000,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 10 10,30 30,40 40)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_CRosses(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -974,6 +1011,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE ST_Crosses(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -992,14 +1030,15 @@ c1 ST_Astext(c4) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where +# Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 10 POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010)) @@ -1010,10 +1049,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -1029,7 +1069,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 30 30,40 40,50 50)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -1041,10 +1081,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the Overelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) @@ -1065,14 +1106,15 @@ c1 ST_Astext(c4) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 8 Using where EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 8 Using where +# Test the ST_Touches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 2 POLYGON((40 50,40 70,50 100,70 100,80 80,70 50,40 50)) @@ -1086,7 +1128,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 100 100,200 200,300 300)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 4 POLYGON((300 300,400 400,500 500,300 500,300 400,300 300)) @@ -1097,10 +1139,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE ST_Touches(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) @@ -1114,7 +1157,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -1125,6 +1168,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra @@ -1143,14 +1187,15 @@ c1 ST_Astext(c4) EXPLAIN UPDATE tab SET C2 = ST_GeomFromText('POINT(0 0)') WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ALL idx3 NULL NULL NULL 10 Using where +1 SIMPLE tab range idx3 idx3 34 NULL 9 Using where +# Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 10 POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010)) @@ -1161,10 +1206,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -1180,7 +1226,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET @g1 = ST_GeomFromText('LINESTRING( 30 30,40 40,50 50)'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 1 POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) @@ -1192,10 +1238,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBROverelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 3 POLYGON((7 1,6 2,6 3,10 3,10 1,7 1)) @@ -1206,10 +1253,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 1 Using where +# Test the MBRTouches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRTouches(tab.c4, @g1) ORDER BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where; Using filesort +1 SIMPLE tab index idx3 PRIMARY 4 NULL 10 Using where SELECT c1,ST_Astext(c4) FROM tab WHERE MBRTouches(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) 2 POLYGON((40 50,40 70,50 100,70 100,80 80,70 50,40 50)) @@ -1220,6 +1268,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN DELETE FROM tab WHERE MBRTouches(tab.c4, @g1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE tab range idx3 idx3 34 NULL 2 Using where +# Test the Delete & Update SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; c1 ST_Astext(c4) @@ -1243,6 +1292,7 @@ CHECK TABLE tab; Table Op Msg_type Msg_text test.tab check status OK DROP TABLE tab; +# Test check constraint on spatial column CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(c1 > 0) ) ENGINE=InnoDB; ERROR HY000: Illegal parameter data types point and int for operation '>' CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(CAST(c1 AS BINARY) > 0) ) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb_gis/r/rtree.result b/mysql-test/suite/innodb_gis/r/rtree.result index 2fd39f9ca32..9ddcb841cbc 100644 --- a/mysql-test/suite/innodb_gis/r/rtree.result +++ b/mysql-test/suite/innodb_gis/r/rtree.result @@ -11,11 +11,11 @@ test.t1 analyze status OK set @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'); explain select ST_astext(t1.g) from t1 where MBRWithin(t1.g, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL g NULL NULL NULL 5 Using where +1 SIMPLE t1 range g g 34 NULL 5 Using where select ST_astext(t1.g) from t1 where MBRWithin(t1.g, @g1); ST_astext(t1.g) -POINT(1 1) POINT(1.5 1.5) +POINT(1 1) set @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'); delete from t1 where MBRWithin(t1.g, @g1); check table t1; @@ -157,11 +157,11 @@ test.t1 analyze status OK set @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'); explain select ST_astext(t1.g) from t1 where MBRWithin(t1.g, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL g NULL NULL NULL 5 Using where +1 SIMPLE t1 range g g 34 NULL 5 Using where select ST_astext(t1.g) from t1 where MBRWithin(t1.g, @g1); ST_astext(t1.g) -POINT(1 1) POINT(1.5 1.5) +POINT(1 1) set @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'); delete from t1 where MBRWithin(t1.g, @g1); check table t1; diff --git a/mysql-test/suite/innodb_gis/r/rtree_multi_pk.result b/mysql-test/suite/innodb_gis/r/rtree_multi_pk.result index 3e6464df997..bab710a5559 100644 --- a/mysql-test/suite/innodb_gis/r/rtree_multi_pk.result +++ b/mysql-test/suite/innodb_gis/r/rtree_multi_pk.result @@ -11,11 +11,11 @@ test.t1 analyze status OK set @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'); explain select ST_astext(t1.g) from t1 where MBRWithin(t1.g, @g1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL g NULL NULL NULL 5 Using where +1 SIMPLE t1 range g g 34 NULL 5 Using where select ST_astext(t1.g) from t1 where MBRWithin(t1.g, @g1); ST_astext(t1.g) -POINT(1 1) POINT(1.5 1.5) +POINT(1 1) set @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'); delete from t1 where MBRWithin(t1.g, @g1); check table t1; @@ -63,10 +63,10 @@ name ST_AsText(square) small POLYGON((0 0,0 1,1 1,1 0,0 0)) SELECT name, ST_AsText(square) from t1 where MBRDisjoint(@p, square); name ST_AsText(square) -up3 POLYGON((0 3,0 5,2 5,2 3,0 3)) down3 POLYGON((0 -3,0 -1,2 -1,2 -3,0 -3)) -right3 POLYGON((3 0,3 2,5 2,5 0,3 0)) left3 POLYGON((-3 0,-3 2,-1 2,-1 0,-3 0)) +right3 POLYGON((3 0,3 2,5 2,5 0,3 0)) +up3 POLYGON((0 3,0 5,2 5,2 3,0 3)) SELECT name, ST_AsText(square) from t1 where MBREquals(@p, square); name ST_AsText(square) SELECT name, ST_AsText(square) from t1 where MBRIntersects(@p, square); diff --git a/mysql-test/suite/innodb_gis/t/create_spatial_index.test b/mysql-test/suite/innodb_gis/t/create_spatial_index.test index 5278292b56c..178041d0414 100644 --- a/mysql-test/suite/innodb_gis/t/create_spatial_index.test +++ b/mysql-test/suite/innodb_gis/t/create_spatial_index.test @@ -94,9 +94,11 @@ ANALYZE TABLE tab; # Check the spatial relationship between 2 GIS shapes -# Test the MBRContains +--echo # Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); +# Show plan if we cannot use index order +EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1+0; EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; @@ -117,7 +119,7 @@ WHERE MBRContains(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRContains(tab.c4, @g1); -# Test the MBRWithin +--echo # Test the MBRWithin SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; @@ -129,7 +131,7 @@ WHERE MBRWithin(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); -# Test the ST_Crosses +--echo # Test the ST_Crosses SET @g1 = ST_GeomFromText('POLYGON((100 200,200 300,400 500,500 300,300 200,100 300,100 200))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; @@ -152,7 +154,7 @@ WHERE ST_Crosses(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE ST_Crosses(tab.c4, @g1); -# Test the MBRDisjoint +--echo # Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; @@ -164,7 +166,7 @@ WHERE MBRDisjoint(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); -# Test the MBREquals +--echo # Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; @@ -176,7 +178,6 @@ WHERE MBREquals(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); -# Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; @@ -199,7 +200,7 @@ WHERE MBRintersects(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); -# Test the Overelaps +--echo # Test the Overelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; @@ -222,7 +223,7 @@ WHERE MBROverlaps(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); -# Test the ST_Touches +--echo # Test the ST_Touches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; @@ -245,7 +246,7 @@ WHERE ST_Touches(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE ST_Touches(tab.c4, @g1); -# Test the MBRContains +--echo # Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; @@ -268,7 +269,7 @@ WHERE MBRWithin(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); -# Test the MBRDisjoint +--echo # Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; @@ -280,7 +281,7 @@ WHERE MBRDisjoint(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); -# Test the MBREquals +--echo # Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; @@ -292,7 +293,7 @@ WHERE MBREquals(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); -# Test the MBRintersects +--echo # Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; @@ -315,7 +316,7 @@ WHERE MBRintersects(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); -# Test the MBROverelaps +--echo # Test the MBROverelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; @@ -327,7 +328,7 @@ WHERE MBROverlaps(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); -# Test the MBRTouches +--echo # Test the MBRTouches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRTouches(tab.c4, @g1) ORDER BY c1; @@ -339,7 +340,7 @@ WHERE MBRTouches(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRTouches(tab.c4, @g1); -# Test with Procedure +--echo # Test with Procedure delimiter |; CREATE PROCEDURE proc_wl6968() @@ -357,7 +358,7 @@ delimiter ;| CALL proc_wl6968(); -# Test the Delete & Update +--echo # Test the Delete & Update SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; @@ -478,7 +479,7 @@ ANALYZE TABLE tab; # Check the spatial relationship between 2 GIS shapes -# Test the MBRContains +--echo # Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; @@ -501,7 +502,7 @@ WHERE MBRContains(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRContains(tab.c4, @g1); -# Test the MBRWithin +--echo # Test the MBRWithin SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; @@ -513,7 +514,7 @@ WHERE MBRWithin(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); -# Test the ST_Crosses +--echo # Test the ST_Crosses SET @g1 = ST_GeomFromText('POLYGON((100 200,200 300,400 500,500 300,300 200,100 300,100 200))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; @@ -536,7 +537,7 @@ WHERE ST_Crosses(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE ST_Crosses(tab.c4, @g1); -# Test the MBRDisjoint +--echo # Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; @@ -548,7 +549,7 @@ WHERE MBRDisjoint(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); -# Test the MBREquals +--echo # Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; @@ -560,7 +561,7 @@ WHERE MBREquals(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); -# Test the MBRintersects +--echo # Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; @@ -583,7 +584,7 @@ WHERE MBRintersects(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); -# Test the Overelaps +--echo # Test the Overelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; @@ -606,7 +607,7 @@ WHERE MBROverlaps(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); -# Test the ST_Touches +--echo # Test the ST_Touches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; @@ -629,7 +630,7 @@ WHERE ST_Touches(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE ST_Touches(tab.c4, @g1); -# Test the MBRContains +--echo # Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; @@ -652,7 +653,7 @@ WHERE MBRWithin(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); -# Test the MBRDisjoint +--echo # Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; @@ -664,7 +665,7 @@ WHERE MBRDisjoint(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); -# Test the MBREquals +--echo # Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; @@ -676,7 +677,7 @@ WHERE MBREquals(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); -# Test the MBRintersects +--echo # Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; @@ -699,7 +700,7 @@ WHERE MBRintersects(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); -# Test the MBROverelaps +--echo # Test the MBROverelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; @@ -711,7 +712,7 @@ WHERE MBROverlaps(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); -# Test the MBRTouches +--echo # Test the MBRTouches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRTouches(tab.c4, @g1) ORDER BY c1; @@ -723,7 +724,7 @@ WHERE MBRTouches(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRTouches(tab.c4, @g1); -# Test with Procedure +--echo # Test with Procedure delimiter |; CREATE PROCEDURE proc_wl6968() @@ -741,7 +742,7 @@ delimiter ;| CALL proc_wl6968(); -# Test the Delete & Update +--echo # Test the Delete & Update SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; @@ -850,7 +851,7 @@ ANALYZE TABLE tab; # Check the spatial relationship between 2 GIS shapes -# Test the MBRContains +--echo # Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; @@ -873,7 +874,7 @@ WHERE MBRContains(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRContains(tab.c4, @g1); -# Test the MBRWithin +--echo # Test the MBRWithin SET @g1 = ST_GeomFromText( 'POLYGON((30 30,40 40,50 50,30 50,30 40,30 30)) '); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRWithin(tab.c4, @g1) ORDER BY c1; @@ -885,7 +886,7 @@ WHERE MBRWithin(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); -# Test the ST_Crosses +--echo # Test the ST_Crosses SET @g1 = ST_GeomFromText('POLYGON((100 200,200 300,400 500,500 300,300 200,100 300,100 200))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Crosses(tab.c4, @g1) ORDER BY c1; @@ -908,7 +909,7 @@ WHERE ST_Crosses(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE ST_Crosses(tab.c4, @g1); -# Test the MBRDisjoint +--echo # Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; @@ -920,7 +921,7 @@ WHERE MBRDisjoint(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); -# Test the MBREquals +--echo # Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; @@ -932,7 +933,7 @@ WHERE MBREquals(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); -# Test the MBRintersects +--echo # Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; @@ -955,7 +956,7 @@ WHERE MBRintersects(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); -# Test the Overelaps +--echo # Test the Overelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; @@ -978,7 +979,7 @@ WHERE MBROverlaps(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); -# Test the ST_Touches +--echo # Test the ST_Touches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE ST_Touches(tab.c4, @g1) ORDER BY c1; @@ -1001,7 +1002,7 @@ WHERE ST_Touches(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE ST_Touches(tab.c4, @g1); -# Test the MBRContains +--echo # Test the MBRContains SET @g1 = ST_GeomFromText( 'POLYGON((7 1,6 2,6 3,10 3,10 1,7 1))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRContains(tab.c4, @g1) ORDER BY c1; @@ -1024,7 +1025,7 @@ WHERE MBRWithin(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRWithin(tab.c4, @g1); -# Test the MBRDisjoint +--echo # Test the MBRDisjoint SET @g1 = ST_GeomFromText('POLYGON((4 -2,5 -4,6 -5,7 -4,7 2,4 -2))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRDisjoint(tab.c4, @g1) ORDER BY c1; @@ -1036,7 +1037,7 @@ WHERE MBRDisjoint(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRDisjoint(tab.c4, @g1); -# Test the MBREquals +--echo # Test the MBREquals SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; @@ -1048,7 +1049,7 @@ WHERE MBREquals(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBREquals(tab.c4, @g1); -# Test the MBRintersects +--echo # Test the MBRintersects SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRIntersects(tab.c4, @g1) ORDER BY c1; @@ -1071,7 +1072,7 @@ WHERE MBRintersects(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRintersects(tab.c4, @g1); -# Test the MBROverelaps +--echo # Test the MBROverelaps SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 2,4 5,5 5,7 1,0 0 ))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBROverlaps(tab.c4, @g1) ORDER BY c1; @@ -1083,7 +1084,7 @@ WHERE MBROverlaps(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBROverlaps(tab.c4, @g1); -# Test the MBRTouches +--echo # Test the MBRTouches SET @g1 = ST_GeomFromText( 'POLYGON((0 0,0 30,30 40,40 50,50 30,0 0))'); EXPLAIN SELECT c1,ST_Astext(c4) FROM tab WHERE MBRTouches(tab.c4, @g1) ORDER BY c1; @@ -1095,7 +1096,7 @@ WHERE MBRTouches(tab.c4, @g1); EXPLAIN DELETE FROM tab WHERE MBRTouches(tab.c4, @g1); -# Test the Delete & Update +--echo # Test the Delete & Update SET @g1 = ST_GeomFromText('POLYGON((5010 5010,5020 5020,5030 5030,5040 5030,5020 5010,5010 5010))'); SELECT c1,ST_Astext(c4) FROM tab WHERE MBREquals(tab.c4, @g1) ORDER BY c1; @@ -1124,7 +1125,7 @@ DROP TABLE tab; # End of Testcase compress table with Auto_increment -# Test check constraint on spatial column +--echo # Test check constraint on spatial column --error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(c1 > 0) ) ENGINE=InnoDB; CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(CAST(c1 AS BINARY) > 0) ) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb_gis/t/rtree_multi_pk.test b/mysql-test/suite/innodb_gis/t/rtree_multi_pk.test index f606e569376..567e16947b7 100644 --- a/mysql-test/suite/innodb_gis/t/rtree_multi_pk.test +++ b/mysql-test/suite/innodb_gis/t/rtree_multi_pk.test @@ -66,6 +66,7 @@ INSERT INTO t1 VALUES("left3", ST_GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 SET @p = ST_GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))'); SELECT name, ST_AsText(square) from t1 where MBRContains(@p, square); +--sorted_result SELECT name, ST_AsText(square) from t1 where MBRDisjoint(@p, square); SELECT name, ST_AsText(square) from t1 where MBREquals(@p, square); SELECT name, ST_AsText(square) from t1 where MBRIntersects(@p, square); diff --git a/mysql-test/suite/json/r/json_table.result b/mysql-test/suite/json/r/json_table.result index 44957352865..900348d8a13 100644 --- a/mysql-test/suite/json/r/json_table.result +++ b/mysql-test/suite/json/r/json_table.result @@ -211,12 +211,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "tt", "access_type": "ALL", + "loops": 1, "rows": 40, + "cost": "COST_REPLACED", "filtered": 100, "table_function": "json_table" } diff --git a/mysql-test/suite/json/r/json_table_mysql.result b/mysql-test/suite/json/r/json_table_mysql.result index 2357d9d3cf0..0be40a8a5c8 100644 --- a/mysql-test/suite/json/r/json_table_mysql.result +++ b/mysql-test/suite/json/r/json_table_mysql.result @@ -189,12 +189,15 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { "table_name": "tt", "access_type": "ALL", + "loops": 1, "rows": 40, + "cost": "COST_REPLACED", "filtered": 100, "table_function": "json_table" } @@ -530,8 +533,7 @@ EXPLAIN SELECT * FROM t1 WHERE id IN (id INT PATH '$')) AS jt); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED jt ALL NULL NULL NULL NULL 40 Table function: json_table +1 PRIMARY jt ALL NULL NULL NULL NULL 40 Table function: json_table; Using where; FirstMatch(t1); Using join buffer (flat, BNL join) DROP TABLE t1; SELECT * FROM JSON_TABLE('"asdf"', '$' COLUMNS( tm TIME PATH '$', diff --git a/mysql-test/suite/json/t/json_table.test b/mysql-test/suite/json/t/json_table.test index 05db8f66a59..982922ff595 100644 --- a/mysql-test/suite/json/t/json_table.test +++ b/mysql-test/suite/json/t/json_table.test @@ -69,6 +69,7 @@ insert into t1 select * from t1; set @save_optimizer_switch=@@optimizer_switch; set optimizer_switch='firstmatch=off'; +--sorted_result select * from json_table('[{"color": "blue", "price": 50}, {"color": "red", "price": 100}]', @@ -144,6 +145,7 @@ create view v2 as select * from json_table('[{"co\\\\lor": "blue", "price": 50 select * from v2; drop view v2; +--source include/explain-no-costs.inc explain format=json select * from json_table('[{"a": 1, "b": [11,111]}, {"a": 2, "b": [22,222]}]', '$[*]' COLUMNS( a INT PATH '$.a')) as tt; explain select * from diff --git a/mysql-test/suite/json/t/json_table_mysql.test b/mysql-test/suite/json/t/json_table_mysql.test index 9f77ad964f3..3b0fb556260 100644 --- a/mysql-test/suite/json/t/json_table_mysql.test +++ b/mysql-test/suite/json/t/json_table_mysql.test @@ -167,6 +167,7 @@ select * from #eval $query; #eval explain $query; +--source include/explain-no-costs.inc explain format=json select * from json_table( diff --git a/mysql-test/suite/maria/icp.result b/mysql-test/suite/maria/icp.result index 43ec6439144..d990d8b0855 100644 --- a/mysql-test/suite/maria/icp.result +++ b/mysql-test/suite/maria/icp.result @@ -409,7 +409,7 @@ WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240 ORDER BY c1 LIMIT 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,k1 PRIMARY 4 NULL 3 Using index condition; Using where; Rowid-ordered scan; Using filesort +1 SIMPLE t1 range|filter PRIMARY,k1 k1|PRIMARY 5|4 NULL 4 (38%) Using index condition; Using where; Using rowid filter DROP TABLE t1; # # @@ -450,9 +450,10 @@ c1 INT NOT NULL, PRIMARY KEY (pk) ); INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1); +insert into t1 select seq,seq from seq_100_to_110; EXPLAIN SELECT pk, c1 FROM t1 WHERE (pk<3 or pk>3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 5 Using where +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 16 Using index condition; Rowid-ordered scan SET SESSION optimizer_switch='index_condition_pushdown=off'; SELECT pk, c1 FROM t1 WHERE (pk<3 or pk>3); pk c1 @@ -460,6 +461,17 @@ pk c1 2 7 4 3 5 1 +100 100 +101 101 +102 102 +103 103 +104 104 +105 105 +106 106 +107 107 +108 108 +109 109 +110 110 DROP TABLE t1; set optimizer_switch= @save_optimizer_switch; # @@ -677,7 +689,6 @@ DROP TABLE t1; # CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b)); INSERT INTO t1 VALUES (1,4,'Ill'); -insert into t1 select seq+100,5,seq from seq_1_to_100; CREATE TABLE t2 (a varchar(1024), KEY (a(512))); INSERT INTO t2 VALUES ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w'); @@ -687,8 +698,8 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL # Using where; Using filesort -1 SIMPLE t2 ref a a 515 test.t1.a # Using where +1 SIMPLE t1 system PRIMARY NULL NULL NULL # +1 SIMPLE t2 ref a a 515 const # Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) HAVING t1.c != 5 ORDER BY t1.c; b c @@ -698,8 +709,8 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL # Using where; Using filesort -1 SIMPLE t2 ref a a 515 test.t1.a # Using where +1 SIMPLE t1 system PRIMARY NULL NULL NULL # +1 SIMPLE t2 ref a a 515 const # Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND (t1.b<0 OR t1.b>0) HAVING t1.c != 5 ORDER BY t1.c; b c @@ -811,6 +822,8 @@ test.t2 analyze status Engine-independent statistics collected test.t2 analyze status Table is already up to date SET @save_optimize_switch=@@optimizer_switch; SET optimizer_switch='materialization=on'; +set @save_optimizer_where_cost=@@optimizer_where_cost; +set @@optimizer_where_cost=1; EXPLAIN SELECT COUNT(*) FROM t1 AS t, t2 WHERE c = g @@ -834,6 +847,7 @@ OR a = 0 AND h < 'z' ); COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; +set @@optimizer_where_cost=@save_optimizer_where_cost; DROP TABLE t1,t2; # check "Handler_pushed" status varuiables CREATE TABLE t1 ( diff --git a/mysql-test/suite/maria/mrr.result b/mysql-test/suite/maria/mrr.result index 066f1a50aab..2c8c289f4a6 100644 --- a/mysql-test/suite/maria/mrr.result +++ b/mysql-test/suite/maria/mrr.result @@ -364,9 +364,9 @@ EXPLAIN SELECT COUNT(t1.v) FROM t1, t2 IGNORE INDEX (idx), t3 IGNORE INDEX (idx) WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL idx 7 NULL 15 Using index -1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 16 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t3 ALL PRIMARY NULL NULL NULL 25 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 16 Using index condition; Rowid-ordered scan +1 SIMPLE t1 index NULL idx 7 NULL 15 Using index; Using join buffer (flat, BNL join) +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 25 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) SELECT COUNT(t1.v) FROM t1, t2, t3 WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0; COUNT(t1.v) @@ -375,9 +375,9 @@ EXPLAIN SELECT COUNT(t1.v) FROM t1, t2, t3 WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL idx 7 NULL 15 Using index -1 SIMPLE t2 ALL PRIMARY,idx NULL NULL NULL 16 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 range PRIMARY,idx PRIMARY 4 NULL 16 Using index condition; Rowid-ordered scan 1 SIMPLE t3 ref PRIMARY,idx idx 3 test.t2.v 2 Using index condition; Using where +1 SIMPLE t1 index NULL idx 7 NULL 15 Using index; Using join buffer (flat, BNL join) set join_cache_level=@save_join_cache_level; DROP TABLE t1,t2,t3; # @@ -405,7 +405,7 @@ WHERE table1.col_varchar_1024_latin1_key = table2.col_varchar_10_latin1 AND table1.pk<>0 ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE table2 ALL NULL NULL NULL NULL 2 Using where -1 SIMPLE table1 ref PRIMARY,col_varchar_1024_latin1_key col_varchar_1024_latin1_key 1027 test.table2.col_varchar_10_latin1 2 Using index condition(BKA); Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE table1 ref PRIMARY,col_varchar_1024_latin1_key col_varchar_1024_latin1_key 1027 test.table2.col_varchar_10_latin1 1 Using index condition(BKA); Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan SELECT count(*) FROM t1 AS table1, t2 AS table2 WHERE diff --git a/mysql-test/suite/mtr/t/simple,c2,s1.rdiff b/mysql-test/suite/mtr/t/simple,c2,s1.rdiff index 3023756aa8a..91f800a6211 100644 --- a/mysql-test/suite/mtr/t/simple,c2,s1.rdiff +++ b/mysql-test/suite/mtr/t/simple,c2,s1.rdiff @@ -1,5 +1,5 @@ ---- suite/mtr/t/simple.result 2012-02-04 12:13:41.000000000 +0100 -+++ suite/mtr/t/simple,infile,verbose.reject 2012-02-04 12:16:10.000000000 +0100 +--- suite/mtr/t/simple.result ++++ suite/mtr/t/simple,infile,verbose.reject @@ -3,7 +3,7 @@ proxy select @@local_infile; diff --git a/mysql-test/suite/mtr/t/simple,s2,c2.rdiff b/mysql-test/suite/mtr/t/simple,s2,c2.rdiff index a9b9b56ef1c..a4c9ab968c5 100644 --- a/mysql-test/suite/mtr/t/simple,s2,c2.rdiff +++ b/mysql-test/suite/mtr/t/simple,s2,c2.rdiff @@ -1,5 +1,5 @@ ---- suite/mtr/t/simple,old.result 2012-02-04 12:13:25.000000000 +0100 -+++ suite/mtr/t/simple,old,infile.reject 2012-02-04 12:13:59.000000000 +0100 +--- suite/mtr/t/simple,old.result ++++ suite/mtr/t/simple,old,infile.reject @@ -3,7 +3,7 @@ proxy select @@local_infile; diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result index 79100ca2b48..17edbc19e0e 100644 --- a/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result +++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result @@ -29,10 +29,10 @@ SELECT `int_key` FROM t2 WHERE `date_nokey` < `datetime_nokey` XOR OUTR .`date_nokey` ) ; pk -9 2 5 6 +9 SELECT `pk` FROM t1 WHERE `pk` IN ( diff --git a/mysql-test/suite/parts/inc/partition_decimal.inc b/mysql-test/suite/parts/inc/partition_decimal.inc index 93e9e48c9c9..4ad2a000355 100644 --- a/mysql-test/suite/parts/inc/partition_decimal.inc +++ b/mysql-test/suite/parts/inc/partition_decimal.inc @@ -6,9 +6,11 @@ partition pa3 max_rows=30 min_rows=4, partition pa4 max_rows=40 min_rows=2); show create table t1; insert into t1 values (999999.9999), (-999999.9999), (123456.7899), (-123456.7899), (-1.5), (1), (0), (-1), (1.5), (1234.567), (-1234.567); +--sorted_result select * from t1; select * from t1 where a=1234.567; delete from t1 where a=1234.567; +--sorted_result select * from t1; drop table t1; @@ -16,9 +18,11 @@ eval create table t2 (a decimal(18,9) not null, primary key(a)) engine=$engine partition by key (a) partitions 10; show create table t2; insert into t2 values (999999999.999999999), (-999999999.999999999), (-1.5), (-1), (0), (1.5), (1234.567), (-1234.567); +--sorted_result select * from t2; select * from t2 where a=1234.567; delete from t2 where a=1234.567; +--sorted_result select * from t2; delete from t2; let $count=$maxrows; diff --git a/mysql-test/suite/parts/inc/partition_double.inc b/mysql-test/suite/parts/inc/partition_double.inc index 9e43887be09..dd2fd10090d 100644 --- a/mysql-test/suite/parts/inc/partition_double.inc +++ b/mysql-test/suite/parts/inc/partition_double.inc @@ -6,9 +6,11 @@ partition pa3 max_rows=30 min_rows=4, partition pa4 max_rows=40 min_rows=2); show create table t1; insert into t1 values (-2.2250738585072014E+208), (-2.2250738585072014E-208), (-1.5), (-1), (0), (1.5), (1234.567), (2.2250738585072014E+208); +--sorted_result select * from t1; select * from t1 where a=1.5; delete from t1 where a=1.5; +--sorted_result select * from t1; drop table t1; @@ -16,9 +18,11 @@ eval create table t2 (a double not null, primary key(a)) engine=$engine partition by key (a) partitions 10; show create table t2; insert into t2 values (-2.2250738585072014E+208), (-2.2250738585072014E-208), (-1.5), (-1), (0), (1.5), (1234.567), (2.2250738585072014E+208); +--sorted_result select * from t2; select * from t2 where a=1234.567; delete from t2 where a=1234.567; +--sorted_result select * from t2; delete from t2; let $count=$maxrows; diff --git a/mysql-test/suite/parts/inc/partition_key_16col.inc b/mysql-test/suite/parts/inc/partition_key_16col.inc index 988dc4554ab..e7917451f1f 100644 --- a/mysql-test/suite/parts/inc/partition_key_16col.inc +++ b/mysql-test/suite/parts/inc/partition_key_16col.inc @@ -10,6 +10,7 @@ insert into t1 values ('1983-12-31', 'cdef', 'srtbvsr', 'w', 45634, 13452.56, 3452346456, 127,'1983-12-31', 'cdef', 'srtbvsr', 'w', 45634, 13452.56, 3452346456, 127, 'liuugbzvdmrlti b itiortudirtfgtibm dfi'), ('1980-10-14', 'fgbbd', 'dtzndtz', 'w', 67856, 5463354.67, 3567845333, 124,'1980-10-14', 'fgbbd', 'dtzndtz', 'w', 67856, 5463354.67, 3567845333, 124, 'd,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr'), ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m'); +--sorted_result select * from t1; select * from t1 where a<19851231; drop table t1; diff --git a/mysql-test/suite/parts/inc/partition_key_32col.inc b/mysql-test/suite/parts/inc/partition_key_32col.inc index 0acedefaa8e..880751db52a 100644 --- a/mysql-test/suite/parts/inc/partition_key_32col.inc +++ b/mysql-test/suite/parts/inc/partition_key_32col.inc @@ -28,6 +28,7 @@ insert into t1 values ('1983-12-31', 'cdef', 'srtbvsr', 'w', 45634, 13452.56, 3452346456, 127,'1983-12-31', 'cdef', 'srtbvsr', 'w', 45634, 13452.56, 3452346456, 127, '1983-12-31', 'cdef', 'srtbvsr', 'w', 45634, 13452.56, 3452346456, 127, '1983-12-31', 'cdef', 'srtbvsr', 'w', 45634, 13452.56, 3452346456, 127, 'liuugbzvdmrlti b itiortudirtfgtibm dfi'), ('1980-10-14', 'fgbbd', 'dtzndtz', 'w', 67856, 5463354.67, 3567845333, 124, '1980-10-14', 'fgbbd', 'dtzndtz', 'w', 67856, 5463354.67, 3567845333, 124, '1980-10-14', 'fgbbd', 'dtzndtz', 'w', 67856, 5463354.67, 3567845333, 124, '1980-10-14', 'fgbbd', 'dtzndtz', 'w', 67856, 5463354.67, 3567845333, 124, 'd,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr'), ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m'); +--sorted_result select * from t1; select * from t1 where a<19851231; drop table t1; diff --git a/mysql-test/suite/parts/inc/partition_key_4col.inc b/mysql-test/suite/parts/inc/partition_key_4col.inc index a94ab581620..706c8addc7e 100644 --- a/mysql-test/suite/parts/inc/partition_key_4col.inc +++ b/mysql-test/suite/parts/inc/partition_key_4col.inc @@ -10,6 +10,7 @@ insert into t1 values ('1983-12-31', 'cdef', 'srtbvsr', 'w'), ('1980-10-14', 'fgbbd', 'dtzndtz', 'w'), ('2000-06-15', 'jukg','zikhuk','m'); +--sorted_result select * from t1; select * from t1 where a<19851231; drop table t1; diff --git a/mysql-test/suite/parts/inc/partition_key_8col.inc b/mysql-test/suite/parts/inc/partition_key_8col.inc index fcbab7c355d..1e49ee0b342 100644 --- a/mysql-test/suite/parts/inc/partition_key_8col.inc +++ b/mysql-test/suite/parts/inc/partition_key_8col.inc @@ -10,6 +10,7 @@ insert into t1 values ('1983-12-31', 'cdef', 'srtbvsr', 'w', 45634, 13452.56, 3452346456, 127, 'liuugbzvdmrlti b itiortudirtfgtibm dfi'), ('1980-10-14', 'fgbbd', 'dtzndtz', 'w', 67856, 5463354.67, 3567845333, 124, 'd,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr'), ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m' ); +--sorted_result select * from t1; select * from t1 where a<19851231; drop table t1; diff --git a/mysql-test/suite/parts/inc/partition_time.inc b/mysql-test/suite/parts/inc/partition_time.inc index 674fe546a1f..5f9466ba64e 100644 --- a/mysql-test/suite/parts/inc/partition_time.inc +++ b/mysql-test/suite/parts/inc/partition_time.inc @@ -57,7 +57,7 @@ dec $count; commit; --enable_query_log select count(*) from t3; -select * from t3; +select a, second(a), if(second(a)<16,1,if(second(a)<31,2,if(second(a)<45,3,4))) from t3; drop table t3; eval create table t4 (a time not null, primary key(a)) engine=$engine diff --git a/mysql-test/suite/parts/inc/partition_timestamp.inc b/mysql-test/suite/parts/inc/partition_timestamp.inc index fb1bf391999..53334c13af0 100644 --- a/mysql-test/suite/parts/inc/partition_timestamp.inc +++ b/mysql-test/suite/parts/inc/partition_timestamp.inc @@ -6,9 +6,11 @@ partition pa3 max_rows=30 min_rows=4, partition pa4 max_rows=40 min_rows=2); show create table t1; insert into t1 values ('1975-01-01 21:21:21'), ('2020-12-31 12:10:30'), ('1980-10-14 03:03'), ('2000-06-15 23:59'); +--sorted_result select * from t1; select * from t1 where a=19801014030300; delete from t1 where a=19801014030300; +--sorted_result select * from t1; drop table t1; @@ -16,9 +18,11 @@ eval create table t2 (a timestamp not null DEFAULT CURRENT_TIMESTAMP ON UPDATE C partition by key (a) partitions 12; show create table t2; insert into t2 values ('1975-01-01 0:1:1'), ('2020-12-31 10:11:12'), ('1980-10-14 13:14:15'), ('2000-06-15 14:15:16'); +--sorted_result select * from t2; select * from t2 where a='1980-10-14 13:14:15'; delete from t2 where a='1980-10-14 13:14:15'; +--sorted_result select * from t2; delete from t2; let $count=59; @@ -33,6 +37,7 @@ dec $count; commit; --enable_query_log select count(*) from t2; +--sorted_result select * from t2; drop table t2; diff --git a/mysql-test/suite/parts/r/optimizer.result b/mysql-test/suite/parts/r/optimizer.result index 42d85dbbd39..95f0e561b0a 100644 --- a/mysql-test/suite/parts/r/optimizer.result +++ b/mysql-test/suite/parts/r/optimizer.result @@ -22,10 +22,10 @@ INSERT INTO t2 SELECT * FROM t1; # plans should be identical EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index +1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index for group-by EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index +1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by FLUSH status; SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a; a MAX(b) @@ -33,7 +33,7 @@ a MAX(b) # Should be no more than 4 reads. SHOW status LIKE 'handler_read_key'; Variable_name Value -Handler_read_key 2 +Handler_read_key 4 FLUSH status; SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a; a MAX(b) @@ -41,5 +41,5 @@ a MAX(b) # Should be no more than 4 reads. SHOW status LIKE 'handler_read_key'; Variable_name Value -Handler_read_key 2 +Handler_read_key 4 DROP TABLE t1, t2; diff --git a/mysql-test/suite/parts/r/partition_char_innodb.result b/mysql-test/suite/parts/r/partition_char_innodb.result index 3131ba58cdf..da6f9bb6c27 100644 Binary files a/mysql-test/suite/parts/r/partition_char_innodb.result and b/mysql-test/suite/parts/r/partition_char_innodb.result differ diff --git a/mysql-test/suite/parts/r/partition_datetime_innodb.result b/mysql-test/suite/parts/r/partition_datetime_innodb.result index 8779bfeafa7..f00b7a3e478 100644 --- a/mysql-test/suite/parts/r/partition_datetime_innodb.result +++ b/mysql-test/suite/parts/r/partition_datetime_innodb.result @@ -145,19 +145,19 @@ t1 CREATE TABLE `t1` ( insert into t1 values ('1975-01-01'), ('2020-12-31'), ('1980-10-14'), ('2000-06-15'); select * from t1; a -1975-01-01 1980-10-14 -2000-06-15 2020-12-31 +1975-01-01 +2000-06-15 select * from t1 where a=19801014; a 1980-10-14 delete from t1 where a=19801014; select * from t1; a +2020-12-31 1975-01-01 2000-06-15 -2020-12-31 drop table t1; create table t2 (a date not null, primary key(a)) engine='InnoDB' partition by key (a) partitions 12; @@ -174,8 +174,8 @@ select * from t2; a 1975-01-01 1980-10-14 -2000-06-15 2020-12-31 +2000-06-15 select * from t2 where a='1980-10-14'; a 1980-10-14 @@ -183,8 +183,8 @@ delete from t2 where a='1980-10-14'; select * from t2; a 1975-01-01 -2000-06-15 2020-12-31 +2000-06-15 delete from t2; 28 inserts; select count(*) from t2; @@ -192,90 +192,90 @@ count(*) 84 select * from t2; a -1970-01-01 -1970-01-02 -1970-01-03 1970-01-04 -1970-01-05 -1970-01-06 -1970-01-07 -1970-01-08 -1970-01-09 -1970-01-10 -1970-01-11 1970-01-12 -1970-01-13 1970-01-14 -1970-01-15 -1970-01-16 -1970-01-17 -1970-01-18 -1970-01-19 -1970-01-20 -1970-01-21 -1970-01-22 -1970-01-23 1970-01-24 -1970-01-25 -1970-01-26 -1970-01-27 1970-01-28 -1970-02-01 1970-02-02 -1970-02-03 1970-02-04 -1970-02-05 -1970-02-06 -1970-02-07 -1970-02-08 -1970-02-09 1970-02-10 -1970-02-11 -1970-02-12 -1970-02-13 1970-02-14 -1970-02-15 1970-02-16 -1970-02-17 -1970-02-18 -1970-02-19 -1970-02-20 -1970-02-21 -1970-02-22 -1970-02-23 -1970-02-24 -1970-02-25 -1970-02-26 -1970-02-27 -1970-02-28 -1970-03-01 -1970-03-02 -1970-03-03 1970-03-04 -1970-03-05 1970-03-06 -1970-03-07 -1970-03-08 -1970-03-09 -1970-03-10 -1970-03-11 1970-03-12 -1970-03-13 -1970-03-14 +1970-01-13 +1970-01-27 +1970-02-03 +1970-02-09 +1970-02-13 +1970-02-21 +1970-03-05 +1970-03-07 +1970-03-09 1970-03-15 -1970-03-16 -1970-03-17 -1970-03-18 -1970-03-19 -1970-03-20 -1970-03-21 -1970-03-22 1970-03-23 +1970-01-06 +1970-01-08 +1970-01-16 +1970-01-18 +1970-01-22 +1970-02-06 +1970-02-12 +1970-02-20 +1970-02-22 +1970-02-28 +1970-03-02 +1970-03-08 +1970-03-16 +1970-03-20 +1970-03-22 1970-03-24 +1970-01-05 +1970-01-07 +1970-01-11 +1970-01-15 +1970-01-21 +1970-02-01 +1970-02-11 +1970-02-15 +1970-02-19 +1970-03-03 +1970-03-11 +1970-03-13 +1970-03-17 +1970-03-19 1970-03-25 -1970-03-26 1970-03-27 +1970-01-02 +1970-01-10 +1970-01-20 +1970-01-26 +1970-02-08 +1970-02-18 +1970-02-24 +1970-02-26 +1970-03-10 +1970-03-14 +1970-03-18 +1970-03-26 1970-03-28 +1970-01-01 +1970-01-03 +1970-01-09 +1970-01-17 +1970-01-19 +1970-01-23 +1970-01-25 +1970-02-05 +1970-02-07 +1970-02-17 +1970-02-23 +1970-02-25 +1970-02-27 +1970-03-01 +1970-03-21 drop table t2; create table t3 (a date not null, primary key(a)) engine='InnoDB' partition by range (month(a)) subpartition by key (a) @@ -304,18 +304,18 @@ count(*) 12 select * from t3; a -1970-01-01 1970-02-01 +1970-01-01 1970-03-01 1970-04-01 1970-05-01 1970-06-01 +1970-09-01 1970-07-01 1970-08-01 -1970-09-01 +1970-12-01 1970-10-01 1970-11-01 -1970-12-01 drop table t3; create table t4 (a date not null, primary key(a)) engine='InnoDB' partition by list (month(a)) subpartition by key (a) @@ -344,18 +344,18 @@ count(*) 12 select * from t4; a -1970-01-01 1970-02-01 +1970-01-01 1970-03-01 1970-04-01 1970-05-01 1970-06-01 +1970-09-01 1970-07-01 1970-08-01 -1970-09-01 +1970-12-01 1970-10-01 1970-11-01 -1970-12-01 drop table t4; create table t1 (a time not null, primary key(a)) engine='InnoDB' partition by key (a) ( @@ -378,18 +378,18 @@ insert into t1 values ('21:21:21'), ('12:10:30'), ('03:03:03'), ('23:59'); select * from t1; a 03:03:03 -12:10:30 21:21:21 23:59:00 +12:10:30 select * from t1 where a=030303; a 03:03:03 delete from t1 where a=030303; select * from t1; a -12:10:30 21:21:21 23:59:00 +12:10:30 drop table t1; create table t2 (a time not null, primary key(a)) engine='InnoDB' partition by key (a) partitions 12; @@ -404,19 +404,19 @@ PARTITIONS 12 insert into t2 values ('0:1:1'), ('10:11:12'), ('13:14:15'), ('14:15:16'); select * from t2; a -00:01:01 10:11:12 13:14:15 14:15:16 +00:01:01 select * from t2 where a='13:14:15'; a 13:14:15 delete from t2 where a='13:14:15'; select * from t2; a -00:01:01 10:11:12 14:15:16 +00:01:01 delete from t2; 59 inserts; select count(*) from t2; @@ -424,65 +424,65 @@ count(*) 59 select * from t2; a -00:01:01 -00:01:02 -00:01:03 -00:01:04 -00:01:05 -00:01:06 -00:01:07 -00:01:08 -00:01:09 -00:01:10 -00:01:11 -00:01:12 -00:01:13 -00:01:14 00:01:15 -00:01:16 -00:01:17 -00:01:18 -00:01:19 -00:01:20 -00:01:21 -00:01:22 00:01:23 -00:01:24 -00:01:25 -00:01:26 -00:01:27 -00:01:28 -00:01:29 -00:01:30 -00:01:31 -00:01:32 -00:01:33 -00:01:34 -00:01:35 -00:01:36 -00:01:37 -00:01:38 00:01:39 -00:01:40 -00:01:41 -00:01:42 -00:01:43 -00:01:44 -00:01:45 -00:01:46 00:01:47 -00:01:48 -00:01:49 -00:01:50 -00:01:51 -00:01:52 -00:01:53 -00:01:54 -00:01:55 -00:01:56 -00:01:57 -00:01:58 00:01:59 +00:01:16 +00:01:24 +00:01:40 +00:01:48 +00:01:05 +00:01:13 +00:01:21 +00:01:37 +00:01:45 +00:01:57 +00:01:14 +00:01:22 +00:01:38 +00:01:46 +00:01:58 +00:01:03 +00:01:11 +00:01:19 +00:01:35 +00:01:43 +00:01:55 +00:01:04 +00:01:12 +00:01:20 +00:01:36 +00:01:44 +00:01:56 +00:01:01 +00:01:09 +00:01:29 +00:01:33 +00:01:41 +00:01:53 +00:01:02 +00:01:10 +00:01:18 +00:01:34 +00:01:42 +00:01:54 +00:01:07 +00:01:27 +00:01:31 +00:01:51 +00:01:08 +00:01:28 +00:01:32 +00:01:52 +00:01:17 +00:01:25 +00:01:49 +00:01:06 +00:01:26 +00:01:30 +00:01:50 drop table t2; create table t3 (a time not null, primary key(a)) engine='InnoDB' partition by range (second(a)) subpartition by key (a) @@ -509,67 +509,67 @@ SUBPARTITIONS 3 select count(*) from t3; count(*) 59 -select * from t3; -a -10:00:01 -10:00:02 -10:00:03 -10:00:04 -10:00:05 -10:00:06 -10:00:07 -10:00:08 -10:00:09 -10:00:10 -10:00:11 -10:00:12 -10:00:13 -10:00:14 -10:00:15 -10:00:16 -10:00:17 -10:00:18 -10:00:19 -10:00:20 -10:00:21 -10:00:22 -10:00:23 -10:00:24 -10:00:25 -10:00:26 -10:00:27 -10:00:28 -10:00:29 -10:00:30 -10:00:31 -10:00:32 -10:00:33 -10:00:34 -10:00:35 -10:00:36 -10:00:37 -10:00:38 -10:00:39 -10:00:40 -10:00:41 -10:00:42 -10:00:43 -10:00:44 -10:00:45 -10:00:46 -10:00:47 -10:00:48 -10:00:49 -10:00:50 -10:00:51 -10:00:52 -10:00:53 -10:00:54 -10:00:55 -10:00:56 -10:00:57 -10:00:58 -10:00:59 +select a, second(a), if(second(a)<16,1,if(second(a)<31,2,if(second(a)<45,3,4))) from t3; +a second(a) if(second(a)<16,1,if(second(a)<31,2,if(second(a)<45,3,4))) +10:00:01 1 1 +10:00:06 6 1 +10:00:07 7 1 +10:00:14 14 1 +10:00:15 15 1 +10:00:02 2 1 +10:00:03 3 1 +10:00:08 8 1 +10:00:09 9 1 +10:00:04 4 1 +10:00:05 5 1 +10:00:10 10 1 +10:00:11 11 1 +10:00:12 12 1 +10:00:13 13 1 +10:00:20 20 2 +10:00:21 21 2 +10:00:26 26 2 +10:00:27 27 2 +10:00:16 16 2 +10:00:17 17 2 +10:00:22 22 2 +10:00:23 23 2 +10:00:28 28 2 +10:00:29 29 2 +10:00:18 18 2 +10:00:19 19 2 +10:00:24 24 2 +10:00:25 25 2 +10:00:30 30 2 +10:00:32 32 3 +10:00:33 33 3 +10:00:35 35 3 +10:00:40 40 3 +10:00:41 41 3 +10:00:34 34 3 +10:00:36 36 3 +10:00:37 37 3 +10:00:42 42 3 +10:00:43 43 3 +10:00:31 31 3 +10:00:38 38 3 +10:00:39 39 3 +10:00:44 44 3 +10:00:45 45 4 +10:00:46 46 4 +10:00:48 48 4 +10:00:49 49 4 +10:00:54 54 4 +10:00:55 55 4 +10:00:50 50 4 +10:00:51 51 4 +10:00:56 56 4 +10:00:57 57 4 +10:00:59 59 4 +10:00:47 47 4 +10:00:52 52 4 +10:00:53 53 4 +10:00:58 58 4 drop table t3; create table t4 (a time not null, primary key(a)) engine='InnoDB' partition by list (second(a)) subpartition by key (a) @@ -599,64 +599,64 @@ count(*) select * from t4; a 10:00:01 -10:00:02 -10:00:03 -10:00:04 -10:00:05 10:00:06 10:00:07 +10:00:14 +10:00:15 +10:00:02 +10:00:03 10:00:08 10:00:09 +10:00:04 +10:00:05 10:00:10 10:00:11 10:00:12 10:00:13 -10:00:14 -10:00:15 -10:00:16 -10:00:17 -10:00:18 -10:00:19 10:00:20 10:00:21 -10:00:22 -10:00:23 -10:00:24 -10:00:25 10:00:26 10:00:27 +10:00:16 +10:00:17 +10:00:22 +10:00:23 10:00:28 10:00:29 +10:00:18 +10:00:19 +10:00:24 +10:00:25 10:00:30 -10:00:31 10:00:32 10:00:33 -10:00:34 10:00:35 -10:00:36 -10:00:37 -10:00:38 -10:00:39 10:00:40 10:00:41 +10:00:34 +10:00:36 +10:00:37 10:00:42 10:00:43 +10:00:31 +10:00:38 +10:00:39 10:00:44 10:00:45 10:00:46 -10:00:47 10:00:48 10:00:49 -10:00:50 -10:00:51 -10:00:52 -10:00:53 10:00:54 10:00:55 +10:00:50 +10:00:51 10:00:56 10:00:57 -10:00:58 10:00:59 +10:00:47 +10:00:52 +10:00:53 +10:00:58 drop table t4; create table t1 (a datetime not null, primary key(a)) engine='InnoDB' partition by key (a) ( @@ -679,9 +679,9 @@ insert into t1 values ('1975-01-01 21:21:21'), ('2020-12-31 12:10:30'), ('1980-1 select * from t1; a 1975-01-01 21:21:21 -1980-10-14 03:03:00 2000-06-15 23:59:00 2020-12-31 12:10:30 +1980-10-14 03:03:00 select * from t1 where a=19801014030300; a 1980-10-14 03:03:00 @@ -705,19 +705,19 @@ PARTITIONS 12 insert into t2 values ('1975-01-01 0:1:1'), ('2020-12-31 10:11:12'), ('1980-10-14 13:14:15'), ('2000-06-15 14:15:16'); select * from t2; a -1975-01-01 00:01:01 -1980-10-14 13:14:15 -2000-06-15 14:15:16 2020-12-31 10:11:12 +2000-06-15 14:15:16 +1980-10-14 13:14:15 +1975-01-01 00:01:01 select * from t2 where a='1980-10-14 13:14:15'; a 1980-10-14 13:14:15 delete from t2 where a='1980-10-14 13:14:15'; select * from t2; a -1975-01-01 00:01:01 -2000-06-15 14:15:16 2020-12-31 10:11:12 +2000-06-15 14:15:16 +1975-01-01 00:01:01 delete from t2; 59 inserts; select count(*) from t2; @@ -725,65 +725,65 @@ count(*) 59 select * from t2; a -1970-01-01 00:00:01 -1970-01-01 00:00:02 -1970-01-01 00:00:03 -1970-01-01 00:00:04 -1970-01-01 00:00:05 -1970-01-01 00:00:06 -1970-01-01 00:00:07 -1970-01-01 00:00:08 1970-01-01 00:00:09 -1970-01-01 00:00:10 -1970-01-01 00:00:11 -1970-01-01 00:00:12 1970-01-01 00:00:13 -1970-01-01 00:00:14 -1970-01-01 00:00:15 -1970-01-01 00:00:16 -1970-01-01 00:00:17 -1970-01-01 00:00:18 1970-01-01 00:00:19 -1970-01-01 00:00:20 -1970-01-01 00:00:21 -1970-01-01 00:00:22 1970-01-01 00:00:23 -1970-01-01 00:00:24 -1970-01-01 00:00:25 -1970-01-01 00:00:26 -1970-01-01 00:00:27 -1970-01-01 00:00:28 -1970-01-01 00:00:29 -1970-01-01 00:00:30 -1970-01-01 00:00:31 -1970-01-01 00:00:32 1970-01-01 00:00:33 -1970-01-01 00:00:34 -1970-01-01 00:00:35 -1970-01-01 00:00:36 1970-01-01 00:00:37 -1970-01-01 00:00:38 -1970-01-01 00:00:39 -1970-01-01 00:00:40 -1970-01-01 00:00:41 -1970-01-01 00:00:42 -1970-01-01 00:00:43 -1970-01-01 00:00:44 -1970-01-01 00:00:45 -1970-01-01 00:00:46 -1970-01-01 00:00:47 -1970-01-01 00:00:48 -1970-01-01 00:00:49 -1970-01-01 00:00:50 1970-01-01 00:00:51 -1970-01-01 00:00:52 -1970-01-01 00:00:53 -1970-01-01 00:00:54 -1970-01-01 00:00:55 -1970-01-01 00:00:56 -1970-01-01 00:00:57 -1970-01-01 00:00:58 1970-01-01 00:00:59 +1970-01-01 00:00:04 +1970-01-01 00:00:10 +1970-01-01 00:00:14 +1970-01-01 00:00:24 +1970-01-01 00:00:28 +1970-01-01 00:00:34 +1970-01-01 00:00:38 +1970-01-01 00:00:48 +1970-01-01 00:00:52 +1970-01-01 00:00:56 +1970-01-01 00:00:03 +1970-01-01 00:00:07 +1970-01-01 00:00:17 +1970-01-01 00:00:21 +1970-01-01 00:00:27 +1970-01-01 00:00:31 +1970-01-01 00:00:35 +1970-01-01 00:00:39 +1970-01-01 00:00:41 +1970-01-01 00:00:45 +1970-01-01 00:00:08 +1970-01-01 00:00:12 +1970-01-01 00:00:18 +1970-01-01 00:00:22 +1970-01-01 00:00:32 +1970-01-01 00:00:36 +1970-01-01 00:00:42 +1970-01-01 00:00:46 +1970-01-01 00:00:01 +1970-01-01 00:00:05 +1970-01-01 00:00:11 +1970-01-01 00:00:15 +1970-01-01 00:00:25 +1970-01-01 00:00:29 +1970-01-01 00:00:43 +1970-01-01 00:00:47 +1970-01-01 00:00:49 +1970-01-01 00:00:53 +1970-01-01 00:00:55 +1970-01-01 00:00:57 +1970-01-01 00:00:02 +1970-01-01 00:00:06 +1970-01-01 00:00:16 +1970-01-01 00:00:20 +1970-01-01 00:00:26 +1970-01-01 00:00:30 +1970-01-01 00:00:40 +1970-01-01 00:00:44 +1970-01-01 00:00:50 +1970-01-01 00:00:54 +1970-01-01 00:00:58 drop table t2; create table t3 (a datetime not null, primary key(a)) engine='InnoDB' partition by range (month(a)) subpartition by key (a) @@ -812,15 +812,15 @@ count(*) 12 select * from t3; a -1970-01-01 00:00:00 1970-02-01 00:00:00 +1970-01-01 00:00:00 1970-03-01 00:00:00 1970-04-01 00:00:00 1970-05-01 00:00:00 1970-06-01 00:00:00 -1970-07-01 00:00:00 1970-08-01 00:00:00 1970-09-01 00:00:00 +1970-07-01 00:00:00 1970-10-01 00:00:00 1970-11-01 00:00:00 1970-12-01 00:00:00 @@ -852,15 +852,15 @@ count(*) 12 select * from t4; a -1970-01-01 00:00:00 1970-02-01 00:00:00 +1970-01-01 00:00:00 1970-03-01 00:00:00 1970-04-01 00:00:00 1970-05-01 00:00:00 1970-06-01 00:00:00 -1970-07-01 00:00:00 1970-08-01 00:00:00 1970-09-01 00:00:00 +1970-07-01 00:00:00 1970-10-01 00:00:00 1970-11-01 00:00:00 1970-12-01 00:00:00 @@ -885,19 +885,19 @@ t1 CREATE TABLE `t1` ( insert into t1 values ('1975'), (2020), ('1980'), ('2000'); select * from t1; a -1975 1980 2000 2020 +1975 select * from t1 where a=1980; a 1980 delete from t1 where a=1980; select * from t1; a -1975 2000 2020 +1975 drop table t1; create table t2 (a year not null, primary key(a)) engine='InnoDB' partition by key (a) partitions 12; @@ -912,19 +912,19 @@ PARTITIONS 12 insert into t2 values ('1975'), ('2020'), ('1980'), ('2000'); select * from t2; a +2020 1975 1980 2000 -2020 select * from t2 where a='1980'; a 1980 delete from t2 where a='1980'; select * from t2; a +2020 1975 2000 -2020 delete from t2; 255 inserts; Warnings: @@ -934,259 +934,259 @@ count(*) 255 select * from t2; a -0000 -1902 -1903 -1904 -1905 -1906 -1907 -1908 1909 -1910 -1911 -1912 -1913 -1914 -1915 -1916 -1917 -1918 -1919 -1920 1921 -1922 -1923 -1924 -1925 -1926 -1927 -1928 -1929 -1930 -1931 -1932 1933 -1934 -1935 -1936 -1937 -1938 -1939 -1940 -1941 -1942 -1943 -1944 1945 -1946 -1947 -1948 -1949 -1950 -1951 -1952 -1953 -1954 -1955 -1956 1957 -1958 -1959 -1960 -1961 -1962 -1963 -1964 -1965 -1966 -1967 -1968 1969 -1970 -1971 -1972 -1973 -1974 -1975 -1976 -1977 -1978 -1979 -1980 1981 -1982 -1983 -1984 -1985 -1986 -1987 -1988 -1989 -1990 -1991 -1992 1993 -1994 -1995 -1996 -1997 -1998 -1999 -2000 2001 -2002 -2003 -2004 -2005 -2006 -2007 -2008 -2009 -2010 -2011 -2012 2013 -2014 -2015 -2016 -2017 -2018 -2019 -2020 -2021 -2022 -2023 -2024 -2025 -2026 -2027 -2028 2029 -2030 -2031 -2032 -2033 -2034 -2035 -2036 -2037 -2038 -2039 -2040 2041 -2042 -2043 -2044 -2045 -2046 -2047 -2048 -2049 -2050 -2051 -2052 2053 -2054 -2055 -2056 -2057 -2058 -2059 -2060 -2061 -2062 -2063 -2064 2065 -2066 -2067 -2068 -2069 -2070 -2071 -2072 -2073 -2074 -2075 -2076 2077 -2078 -2079 -2080 -2081 -2082 -2083 -2084 -2085 -2086 -2087 -2088 2089 -2090 -2091 -2092 -2093 -2094 -2095 -2096 -2097 -2098 -2099 2100 2101 2102 2103 -2104 -2105 -2106 -2107 -2108 -2109 -2110 -2111 -2112 -2113 2114 -2115 -2116 -2117 -2118 -2119 -2120 -2121 -2122 -2123 -2124 -2125 -2126 -2127 -2128 -2129 -2130 -2131 2132 2133 2134 2135 -2136 -2137 -2138 -2139 -2140 -2141 +2146 +1904 +1916 +1928 +1932 +1940 +1952 +1964 +1976 +1988 +2008 +2020 +2024 +2036 +2048 +2060 +2072 +2084 +1907 +1919 +1931 +1943 +1955 +1967 +1979 +1991 +1999 +2011 +2027 +2039 +2051 +2063 +2075 +2087 +2097 +2099 +2110 +2111 +2112 +2113 +2123 +2129 +2131 2142 2143 2144 2145 -2146 2147 +1902 +1914 +1926 +1938 +1950 +1962 +1974 +1986 +2006 +2018 +2034 +2046 +2058 +2070 +2082 +1905 +1917 +1929 +1941 +1953 +1965 +1977 +1989 +1997 +2009 +2021 +2025 +2037 +2049 +2061 +2073 +2085 +2092 +2093 +2094 +2095 +2120 +2121 +2124 +2125 +2126 +2127 +2152 +2153 +0000 +1912 +1924 +1936 +1948 +1960 +1972 +1984 +1996 +2004 +2016 +2032 +2044 +2056 +2068 +2080 +2116 2148 +1903 +1915 +1927 +1939 +1951 +1963 +1975 +1987 +2007 +2019 +2023 +2035 +2047 +2059 +2071 +2083 +2155 +1910 +1922 +1934 +1946 +1958 +1970 +1982 +1994 +2002 +2014 +2030 +2042 +2054 +2066 +2078 +2090 +1913 +1925 +1937 +1949 +1961 +1973 +1985 +2005 +2017 +2033 +2045 +2057 +2069 +2081 +2104 +2105 +2106 +2107 +2117 +2118 +2119 +2136 +2137 +2138 +2139 2149 2150 2151 -2152 -2153 +1908 +1920 +1944 +1956 +1968 +1980 +1992 +2000 +2012 +2028 +2040 +2052 +2064 +2076 +2088 +2096 +2098 +2108 +2128 +2130 +2140 +1911 +1923 +1935 +1947 +1959 +1971 +1983 +1995 +2003 +2015 +2031 +2043 +2055 +2067 +2079 +2091 +2115 +1906 +1918 +1930 +1942 +1954 +1966 +1978 +1990 +1998 +2010 +2022 +2026 +2038 +2050 +2062 +2074 +2086 +2109 +2122 +2141 2154 -2155 drop table t2; diff --git a/mysql-test/suite/parts/r/partition_datetime_myisam.result b/mysql-test/suite/parts/r/partition_datetime_myisam.result index 0d1dcf3ec30..9d8acb09a4a 100644 --- a/mysql-test/suite/parts/r/partition_datetime_myisam.result +++ b/mysql-test/suite/parts/r/partition_datetime_myisam.result @@ -509,67 +509,67 @@ SUBPARTITIONS 3 select count(*) from t3; count(*) 59 -select * from t3; -a -10:00:01 -10:00:02 -10:00:03 -10:00:04 -10:00:05 -10:00:06 -10:00:07 -10:00:08 -10:00:09 -10:00:10 -10:00:11 -10:00:12 -10:00:13 -10:00:14 -10:00:15 -10:00:16 -10:00:17 -10:00:18 -10:00:19 -10:00:20 -10:00:21 -10:00:22 -10:00:23 -10:00:24 -10:00:25 -10:00:26 -10:00:27 -10:00:28 -10:00:29 -10:00:30 -10:00:31 -10:00:32 -10:00:33 -10:00:34 -10:00:35 -10:00:36 -10:00:37 -10:00:38 -10:00:39 -10:00:40 -10:00:41 -10:00:42 -10:00:43 -10:00:44 -10:00:45 -10:00:46 -10:00:47 -10:00:48 -10:00:49 -10:00:50 -10:00:51 -10:00:52 -10:00:53 -10:00:54 -10:00:55 -10:00:56 -10:00:57 -10:00:58 -10:00:59 +select a, second(a), if(second(a)<16,1,if(second(a)<31,2,if(second(a)<45,3,4))) from t3; +a second(a) if(second(a)<16,1,if(second(a)<31,2,if(second(a)<45,3,4))) +10:00:01 1 1 +10:00:02 2 1 +10:00:03 3 1 +10:00:04 4 1 +10:00:05 5 1 +10:00:06 6 1 +10:00:07 7 1 +10:00:08 8 1 +10:00:09 9 1 +10:00:10 10 1 +10:00:11 11 1 +10:00:12 12 1 +10:00:13 13 1 +10:00:14 14 1 +10:00:15 15 1 +10:00:16 16 2 +10:00:17 17 2 +10:00:18 18 2 +10:00:19 19 2 +10:00:20 20 2 +10:00:21 21 2 +10:00:22 22 2 +10:00:23 23 2 +10:00:24 24 2 +10:00:25 25 2 +10:00:26 26 2 +10:00:27 27 2 +10:00:28 28 2 +10:00:29 29 2 +10:00:30 30 2 +10:00:31 31 3 +10:00:32 32 3 +10:00:33 33 3 +10:00:34 34 3 +10:00:35 35 3 +10:00:36 36 3 +10:00:37 37 3 +10:00:38 38 3 +10:00:39 39 3 +10:00:40 40 3 +10:00:41 41 3 +10:00:42 42 3 +10:00:43 43 3 +10:00:44 44 3 +10:00:45 45 4 +10:00:46 46 4 +10:00:47 47 4 +10:00:48 48 4 +10:00:49 49 4 +10:00:50 50 4 +10:00:51 51 4 +10:00:52 52 4 +10:00:53 53 4 +10:00:54 54 4 +10:00:55 55 4 +10:00:56 56 4 +10:00:57 57 4 +10:00:58 58 4 +10:00:59 59 4 drop table t3; create table t4 (a time not null, primary key(a)) engine='MyISAM' partition by list (second(a)) subpartition by key (a) diff --git a/mysql-test/suite/parts/r/partition_decimal_innodb.result b/mysql-test/suite/parts/r/partition_decimal_innodb.result index c2f00a8925e..bce034612dc 100644 --- a/mysql-test/suite/parts/r/partition_decimal_innodb.result +++ b/mysql-test/suite/parts/r/partition_decimal_innodb.result @@ -18,11 +18,11 @@ t1 CREATE TABLE `t1` ( insert into t1 values (999999.9999), (-999999.9999), (123456.7899), (-123456.7899), (-1.5), (1), (0), (-1), (1.5), (1234.567), (-1234.567); select * from t1; a --999999.9999 --123456.7899 --1234.5670 --1.5000 -1.0000 +-1.5000 +-1234.5670 +-123456.7899 +-999999.9999 0.0000 1.0000 1.5000 @@ -35,11 +35,11 @@ a delete from t1 where a=1234.567; select * from t1; a --999999.9999 --123456.7899 --1234.5670 --1.5000 -1.0000 +-1.5000 +-1234.5670 +-123456.7899 +-999999.9999 0.0000 1.0000 1.5000 @@ -59,10 +59,10 @@ PARTITIONS 10 insert into t2 values (999999999.999999999), (-999999999.999999999), (-1.5), (-1), (0), (1.5), (1234.567), (-1234.567); select * from t2; a --999999999.999999999 --1234.567000000 --1.500000000 -1.000000000 +-1.500000000 +-1234.567000000 +-999999999.999999999 0.000000000 1.500000000 1234.567000000 @@ -73,10 +73,10 @@ a delete from t2 where a=1234.567; select * from t2; a --999999999.999999999 --1234.567000000 --1.500000000 -1.000000000 +-1.500000000 +-1234.567000000 +-999999999.999999999 0.000000000 1.500000000 999999999.999999999 diff --git a/mysql-test/suite/parts/r/partition_decimal_myisam.result b/mysql-test/suite/parts/r/partition_decimal_myisam.result index a5175079a4b..90ea5ea83ef 100644 --- a/mysql-test/suite/parts/r/partition_decimal_myisam.result +++ b/mysql-test/suite/parts/r/partition_decimal_myisam.result @@ -18,11 +18,11 @@ t1 CREATE TABLE `t1` ( insert into t1 values (999999.9999), (-999999.9999), (123456.7899), (-123456.7899), (-1.5), (1), (0), (-1), (1.5), (1234.567), (-1234.567); select * from t1; a --999999.9999 --123456.7899 --1234.5670 --1.5000 -1.0000 +-1.5000 +-1234.5670 +-123456.7899 +-999999.9999 0.0000 1.0000 1.5000 @@ -35,11 +35,11 @@ a delete from t1 where a=1234.567; select * from t1; a --999999.9999 --123456.7899 --1234.5670 --1.5000 -1.0000 +-1.5000 +-1234.5670 +-123456.7899 +-999999.9999 0.0000 1.0000 1.5000 @@ -59,10 +59,10 @@ PARTITIONS 10 insert into t2 values (999999999.999999999), (-999999999.999999999), (-1.5), (-1), (0), (1.5), (1234.567), (-1234.567); select * from t2; a --999999999.999999999 --1234.567000000 --1.500000000 -1.000000000 +-1.500000000 +-1234.567000000 +-999999999.999999999 0.000000000 1.500000000 1234.567000000 @@ -73,10 +73,10 @@ a delete from t2 where a=1234.567; select * from t2; a --999999999.999999999 --1234.567000000 --1.500000000 -1.000000000 +-1.500000000 +-1234.567000000 +-999999999.999999999 0.000000000 1.500000000 999999999.999999999 diff --git a/mysql-test/suite/parts/r/partition_double_innodb.result b/mysql-test/suite/parts/r/partition_double_innodb.result index 7563109f30b..41834075790 100644 --- a/mysql-test/suite/parts/r/partition_double_innodb.result +++ b/mysql-test/suite/parts/r/partition_double_innodb.result @@ -18,10 +18,10 @@ t1 CREATE TABLE `t1` ( insert into t1 values (-2.2250738585072014E+208), (-2.2250738585072014E-208), (-1.5), (-1), (0), (1.5), (1234.567), (2.2250738585072014E+208); select * from t1; a --2.2250738585072016e208 --1.5 -1 +-1.5 -2.2250738585072014e-208 +-2.2250738585072016e208 0 1.5 1234.567 @@ -32,10 +32,10 @@ a delete from t1 where a=1.5; select * from t1; a --2.2250738585072016e208 --1.5 -1 +-1.5 -2.2250738585072014e-208 +-2.2250738585072016e208 0 1234.567 2.2250738585072016e208 @@ -53,10 +53,10 @@ PARTITIONS 10 insert into t2 values (-2.2250738585072014E+208), (-2.2250738585072014E-208), (-1.5), (-1), (0), (1.5), (1234.567), (2.2250738585072014E+208); select * from t2; a --2.2250738585072016e208 --1.5 -1 +-1.5 -2.2250738585072014e-208 +-2.2250738585072016e208 0 1.5 1234.567 @@ -67,10 +67,10 @@ a delete from t2 where a=1234.567; select * from t2; a --2.2250738585072016e208 --1.5 -1 +-1.5 -2.2250738585072014e-208 +-2.2250738585072016e208 0 1.5 2.2250738585072016e208 diff --git a/mysql-test/suite/parts/r/partition_double_myisam.result b/mysql-test/suite/parts/r/partition_double_myisam.result index e9cf25e6408..f2161d42918 100644 --- a/mysql-test/suite/parts/r/partition_double_myisam.result +++ b/mysql-test/suite/parts/r/partition_double_myisam.result @@ -18,10 +18,10 @@ t1 CREATE TABLE `t1` ( insert into t1 values (-2.2250738585072014E+208), (-2.2250738585072014E-208), (-1.5), (-1), (0), (1.5), (1234.567), (2.2250738585072014E+208); select * from t1; a --2.2250738585072016e208 --1.5 -1 +-1.5 -2.2250738585072014e-208 +-2.2250738585072016e208 0 1.5 1234.567 @@ -32,10 +32,10 @@ a delete from t1 where a=1.5; select * from t1; a --2.2250738585072016e208 --1.5 -1 +-1.5 -2.2250738585072014e-208 +-2.2250738585072016e208 0 1234.567 2.2250738585072016e208 @@ -53,10 +53,10 @@ PARTITIONS 10 insert into t2 values (-2.2250738585072014E+208), (-2.2250738585072014E-208), (-1.5), (-1), (0), (1.5), (1234.567), (2.2250738585072014E+208); select * from t2; a --2.2250738585072016e208 --1.5 -1 +-1.5 -2.2250738585072014e-208 +-2.2250738585072016e208 0 1.5 1234.567 @@ -67,10 +67,10 @@ a delete from t2 where a=1234.567; select * from t2; a --2.2250738585072016e208 --1.5 -1 +-1.5 -2.2250738585072014e-208 +-2.2250738585072016e208 0 1.5 2.2250738585072016e208 diff --git a/mysql-test/suite/parts/r/partition_float_innodb.result b/mysql-test/suite/parts/r/partition_float_innodb.result index 7cdccdb886f..c82609b496c 100644 --- a/mysql-test/suite/parts/r/partition_float_innodb.result +++ b/mysql-test/suite/parts/r/partition_float_innodb.result @@ -18,10 +18,10 @@ t1 CREATE TABLE `t1` ( insert into t1 values (-3.402823466E+38), (3.402823466E+38), (-1.5), (-1), (0), (1), (1.5); select * from t1; a +0 -3.40282e38 -1.5 -1 -0 1 1.5 3.40282e38 @@ -31,10 +31,10 @@ a delete from t1 where a=1.5; select * from t1; a +0 -3.40282e38 -1.5 -1 -0 1 3.40282e38 drop table t1; @@ -51,10 +51,10 @@ PARTITIONS 10 insert into t2 values (-3.402823466E+38), (-3.402823466E+37), (-123.456), (0), (1234546.789), (123.456), (1.5); select * from t2; a +0 -3.40282e38 -3.40282e37 -123.456 -0 1.5 123.456 1234550 @@ -63,10 +63,10 @@ a delete from t2 where a=123.456; select * from t2; a +0 -3.40282e38 -3.40282e37 -123.456 -0 1.5 123.456 1234550 @@ -76,10 +76,10 @@ a delete from t2 where a=1.5; select * from t2; a +0 -3.40282e38 -3.40282e37 -123.456 -0 123.456 1234550 delete from t2; diff --git a/mysql-test/suite/parts/r/partition_special_innodb.result b/mysql-test/suite/parts/r/partition_special_innodb.result index 27f8f0a9d5c..2f056de2b7a 100644 --- a/mysql-test/suite/parts/r/partition_special_innodb.result +++ b/mysql-test/suite/parts/r/partition_special_innodb.result @@ -67,9 +67,9 @@ insert into t1 values ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m' ); select * from t1; a b c d e f g h i +1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi -1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m select * from t1 where a<19851231; a b c d e f g h i @@ -117,9 +117,9 @@ insert into t1 values ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m'); select * from t1; a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 i -1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi -1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh +1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr +1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m select * from t1 where a<19851231; a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 i @@ -197,9 +197,9 @@ insert into t1 values ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m'); select * from t1; a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 a3 b3 c3 d3 e3 f3 g3 h3 i +1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi -1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m select * from t1 where a<19851231; a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 a3 b3 c3 d3 e3 f3 g3 h3 i diff --git a/mysql-test/suite/parts/r/partition_special_myisam.result b/mysql-test/suite/parts/r/partition_special_myisam.result index f6ceef4fc77..ce30977cfb7 100644 --- a/mysql-test/suite/parts/r/partition_special_myisam.result +++ b/mysql-test/suite/parts/r/partition_special_myisam.result @@ -67,9 +67,9 @@ insert into t1 values ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m' ); select * from t1; a b c d e f g h i +1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi -1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m select * from t1 where a<19851231; a b c d e f g h i @@ -117,9 +117,9 @@ insert into t1 values ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m'); select * from t1; a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 i -1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi -1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh +1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr +1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m select * from t1 where a<19851231; a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 i @@ -197,9 +197,9 @@ insert into t1 values ('2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, '2000-06-15', 'jukg','zikhuk','m', 45675, 6465754.13, 435242623462, 18, 'pib mdotkbm.m'); select * from t1; a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 a3 b3 c3 d3 e3 f3 g3 h3 i +1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 1980-10-14 fgbbd dtzndtz w 67856 5463354.67 3567845333 124 d,f söierugsig msireg siug ei5ggth lrutluitgzeöjrtnb.rkjthuekuhzrkuthgjdnffjmbr 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 1983-12-31 cdef srtbvsr w 45634 13452.56 3452346456 127 liuugbzvdmrlti b itiortudirtfgtibm dfi -1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 1975-01-01 abcde abcde m 1234 123.45 32412341234 113 tbhth nrzh ztfghgfh fzh ftzhj fztjh 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 2000-06-15 jukg zikhuk m 45675 6465754.13 435242623462 18 pib mdotkbm.m select * from t1 where a<19851231; a b c d e f g h a1 b1 c1 d1 e1 f1 g1 h1 a2 b2 c2 d2 e2 f2 g2 h2 a3 b3 c3 d3 e3 f3 g3 h3 i diff --git a/mysql-test/suite/parts/r/percona_nonflushing_analyze_debug.result b/mysql-test/suite/parts/r/percona_nonflushing_analyze_debug.result index 070d5e8d79f..18afb41f31b 100644 --- a/mysql-test/suite/parts/r/percona_nonflushing_analyze_debug.result +++ b/mysql-test/suite/parts/r/percona_nonflushing_analyze_debug.result @@ -4,7 +4,7 @@ PARTITION p0 VALUES LESS THAN (3), PARTITION p1 VALUES LESS THAN (10)); INSERT INTO t1 VALUES (1), (2), (3), (4); connect con1,localhost,root; -SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; +SET DEBUG_SYNC="handler_rnd_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; SELECT * FROM t1; connection default; SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress"; @@ -39,7 +39,7 @@ PARTITION p0 VALUES LESS THAN (3), PARTITION p1 VALUES LESS THAN (10)); INSERT INTO t2 VALUES (1), (2), (3), (4); connect con1,localhost,root; -SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; +SET DEBUG_SYNC="handler_rnd_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; SELECT * FROM t2; connection default; SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress"; @@ -51,17 +51,17 @@ test.t2 analyze status OK set use_stat_tables=@tmp; SELECT * FROM t2; a -1 2 -3 +1 4 +3 SET DEBUG_SYNC="now SIGNAL finish_scan"; connection con1; a -1 2 -3 +1 4 +3 disconnect con1; connection default; SET DEBUG_SYNC='reset'; diff --git a/mysql-test/suite/perfschema/r/alter_table_progress.result b/mysql-test/suite/perfschema/r/alter_table_progress.result index 08c2c3a6145..31cc60927f6 100644 --- a/mysql-test/suite/perfschema/r/alter_table_progress.result +++ b/mysql-test/suite/perfschema/r/alter_table_progress.result @@ -16,8 +16,6 @@ connection default; SET DEBUG_SYNC='now WAIT_FOR found_row'; select event_id from performance_schema.events_statements_current where thread_id = @con1_thread_id into @con1_stmt_id; -Warnings: -Warning 1287 ' INTO FROM...' instead select EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED from performance_schema.events_stages_current where (thread_id = @con1_thread_id); diff --git a/mysql-test/suite/perfschema/r/batch_table_io_func.result b/mysql-test/suite/perfschema/r/batch_table_io_func.result index 212c08c7e90..4336ebd3bd6 100644 --- a/mysql-test/suite/perfschema/r/batch_table_io_func.result +++ b/mysql-test/suite/perfschema/r/batch_table_io_func.result @@ -154,8 +154,8 @@ alter table t3 add index(id2); explain extended select t1.*, t2.*, t3.* from t1 join t2 using (id1) join t3 using (id2); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL id1 NULL NULL NULL 10 100.00 Using where -1 SIMPLE t2 ref id2,id1 id1 5 test.t1.id1 10 100.00 Using where +1 SIMPLE t1 ALL id1 NULL NULL NULL 10 100.00 +1 SIMPLE t2 ALL id2,id1 NULL NULL NULL 100 10.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 ref id2 id2 5 test.t2.id2 10 100.00 Warnings: Note 1003 select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`id1` AS `id1`,`test`.`t2`.`id2` AS `id2`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`id2` AS `id2`,`test`.`t3`.`id3` AS `id3`,`test`.`t3`.`c` AS `c` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t3`.`id2` = `test`.`t2`.`id2` and `test`.`t2`.`id1` = `test`.`t1`.`id1` @@ -167,7 +167,7 @@ number_seen OBJECT_TYPE OBJECT_SCHEMA OBJECT_NAME INDEX_NAME OPERATION NUMBER_OF 11 TABLE test t1 NULL fetch 1 1 TABLE test t1 id1 read external NULL 1 TABLE test t1 id1 read normal NULL -110 TABLE test t2 id1 fetch 1 +101 TABLE test t2 NULL fetch 1 1 TABLE test t2 id2 read external NULL 1 TABLE test t2 id2 read normal NULL 100 TABLE test t3 id2 fetch 10 @@ -177,14 +177,15 @@ OBJECT_TYPE OBJECT_SCHEMA OBJECT_NAME INDEX_NAME COUNT_STAR COUNT_READ COUNT_WRI TABLE test t0 NULL 0 0 0 TABLE test t1 NULL 11 11 0 TABLE test t1 id1 0 0 0 -TABLE test t2 id1 110 110 0 +TABLE test t2 NULL 101 101 0 +TABLE test t2 id1 0 0 0 TABLE test t2 id2 0 0 0 TABLE test t3 id2 1000 1000 0 TABLE test t3 id3 0 0 0 OBJECT_TYPE OBJECT_SCHEMA OBJECT_NAME COUNT_STAR COUNT_READ COUNT_WRITE TABLE test t0 0 0 0 TABLE test t1 11 11 0 -TABLE test t2 110 110 0 +TABLE test t2 101 101 0 TABLE test t3 1000 1000 0 drop table t0; drop table t1; diff --git a/mysql-test/suite/perfschema/r/dml_handler.result b/mysql-test/suite/perfschema/r/dml_handler.result index 61bbba3189e..1510adc7148 100644 --- a/mysql-test/suite/perfschema/r/dml_handler.result +++ b/mysql-test/suite/perfschema/r/dml_handler.result @@ -6,8 +6,6 @@ SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='performance_schema' ORDER BY TABLE_NAME; SELECT COUNT(*) FROM table_list INTO @table_count; -Warnings: -Warning 1287 ' INTO FROM...' instead # # For each table in the performance schema, attempt HANDLER...OPEN, # which should fail with an error 1031, ER_ILLEGAL_HA. diff --git a/mysql-test/suite/perfschema/r/ortho_iter.result b/mysql-test/suite/perfschema/r/ortho_iter.result index 9489c1049e5..388fac4b668 100644 --- a/mysql-test/suite/perfschema/r/ortho_iter.result +++ b/mysql-test/suite/perfschema/r/ortho_iter.result @@ -218,10 +218,6 @@ close pfs_cursor; signal sqlstate '01000' set message_text='Done', mysql_errno=12000; end $ -Warnings: -Warning 1287 ' INTO FROM...' instead -Warning 1287 ' INTO FROM...' instead -Warning 1287 ' INTO FROM...' instead show global variables like "performance_schema%"; Variable_name Value performance_schema ON diff --git a/mysql-test/suite/perfschema/r/rpl_threads.result b/mysql-test/suite/perfschema/r/rpl_threads.result index c756b4d9046..e9ad54386ab 100644 --- a/mysql-test/suite/perfschema/r/rpl_threads.result +++ b/mysql-test/suite/perfschema/r/rpl_threads.result @@ -16,8 +16,6 @@ connection master; select ID from INFORMATION_SCHEMA.PROCESSLIST where COMMAND = "Binlog Dump" into @master_dump_pid; -Warnings: -Warning 1287 ' INTO FROM...' instead select COMMAND, STATE from INFORMATION_SCHEMA.PROCESSLIST where ID = @master_dump_pid; @@ -33,8 +31,6 @@ connection slave; select ID from INFORMATION_SCHEMA.PROCESSLIST where STATE like "Waiting for master to send event%" into @slave_io_pid; -Warnings: -Warning 1287 ' INTO FROM...' instead select COMMAND, STATE from INFORMATION_SCHEMA.PROCESSLIST where ID = @slave_io_pid; @@ -47,8 +43,6 @@ NAME TYPE PROCESSLIST_COMMAND PROCESSLIST_STATE select ID from INFORMATION_SCHEMA.PROCESSLIST where STATE like "Slave has read all relay log%" into @slave_sql_pid; -Warnings: -Warning 1287 ' INTO FROM...' instead select COMMAND, STATE from INFORMATION_SCHEMA.PROCESSLIST where ID = @slave_sql_pid; diff --git a/mysql-test/suite/perfschema/r/selects.result b/mysql-test/suite/perfschema/r/selects.result index d623d45a6e8..c14d152856f 100644 --- a/mysql-test/suite/perfschema/r/selects.result +++ b/mysql-test/suite/perfschema/r/selects.result @@ -93,8 +93,6 @@ SELECT thread_id FROM performance_schema.threads WHERE PROCESSLIST_ID = conid INTO pid; END; | -Warnings: -Warning 1287 ' INTO FROM...' instead CALL t_ps_proc(connection_id(), @p_id); DROP FUNCTION IF EXISTS t_ps_proc; CREATE FUNCTION t_ps_func(conid INT) RETURNS int diff --git a/mysql-test/suite/period/r/delete,myisam.rdiff b/mysql-test/suite/period/r/delete,myisam.rdiff index 78fb972b0bc..179f399ac9a 100644 --- a/mysql-test/suite/period/r/delete,myisam.rdiff +++ b/mysql-test/suite/period/r/delete,myisam.rdiff @@ -1,5 +1,5 @@ ---- suite/period/r/delete.result 2019-02-16 11:14:23.511258191 +0100 -+++ suite/period/r/delete.reject 2019-02-16 11:14:32.869258690 +0100 +--- suite/period/r/delete.result ++++ suite/period/r/delete.reject @@ -250,7 +250,6 @@ ERROR 22003: Out of range value for column 'id' at row 1 select * from t; diff --git a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test index e86e93f7a3b..e397989bec5 100644 --- a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test +++ b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test @@ -17,7 +17,7 @@ alter table user drop column max_statement_time; flush privileges; ---replace_regex /1\d\d\d\d\d/MYSQL_VERSION_ID/ +--replace_regex /11\d\d\d\d/MYSQL_VERSION_ID/ --error ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE create role test_role; --error ER_CANNOT_USER @@ -30,8 +30,6 @@ after password_expired; create role test_role; create user test_user@localhost; grant test_role to test_user@localhost; -#--replace_regex /10\d\d\d\d/MYSQL_VERSION_ID/ -#--error ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE set default role test_role for root@localhost; drop role test_role; drop user test_user@localhost; diff --git a/mysql-test/suite/rpl/r/rpl_delayed_slave,parallel.rdiff b/mysql-test/suite/rpl/r/rpl_delayed_slave,parallel.rdiff index aaadbb28ca3..d803f8be5c2 100644 --- a/mysql-test/suite/rpl/r/rpl_delayed_slave,parallel.rdiff +++ b/mysql-test/suite/rpl/r/rpl_delayed_slave,parallel.rdiff @@ -1,5 +1,5 @@ ---- mysql-test/suite/rpl/r/rpl_delayed_slave.result 2016-10-14 21:14:02.338075590 +0200 -+++ mysql-test/suite/rpl/r/rpl_delayed_slave,parallel.reject 2016-10-14 21:17:51.296986686 +0200 +--- mysql-test/suite/rpl/r/rpl_delayed_slave.result ++++ mysql-test/suite/rpl/r/rpl_delayed_slave,parallel.reject @@ -45,7 +45,6 @@ # wait for first query to execute # sleep 1*T diff --git a/mysql-test/suite/rpl/r/rpl_drop_db.result b/mysql-test/suite/rpl/r/rpl_drop_db.result index 3712527afe4..1b132c20afc 100644 --- a/mysql-test/suite/rpl/r/rpl_drop_db.result +++ b/mysql-test/suite/rpl/r/rpl_drop_db.result @@ -6,8 +6,6 @@ create database mysqltest1; create table mysqltest1.t1 (n int); insert into mysqltest1.t1 values (1); select * from mysqltest1.t1 into outfile 'mysqltest1/f1.txt'; -Warnings: -Warning 1287 ' INTO FROM...' instead create table mysqltest1.t2 (n int); create table mysqltest1.t3 (n int); drop database mysqltest1; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result b/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result index 2ecc3ac159c..063e568f5fa 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result @@ -51,10 +51,6 @@ DELETE FROM test.regular_tbl WHERE id = del_count; SET del_count = del_count - 2; END WHILE; END| -Warnings: -Level Warning -Code 1287 -Message ' INTO FROM...' instead CREATE PROCEDURE test.proc_bykey() BEGIN DECLARE ins_count INT DEFAULT 1000; @@ -76,10 +72,6 @@ DELETE FROM test.bykey_tbl WHERE id = del_count; SET del_count = del_count - 2; END WHILE; END| -Warnings: -Level Warning -Code 1287 -Message ' INTO FROM...' instead CREATE PROCEDURE test.proc_byrange() BEGIN DECLARE ins_count INT DEFAULT 1000; @@ -101,10 +93,6 @@ DELETE FROM test.byrange_tbl WHERE id = del_count; SET del_count = del_count - 2; END WHILE; END| -Warnings: -Level Warning -Code 1287 -Message ' INTO FROM...' instead begin; CALL test.proc_norm(); commit; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_bug30888.result b/mysql-test/suite/rpl/r/rpl_innodb_bug30888.result index da6888e76a0..d4640a36a7d 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_bug30888.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_bug30888.result @@ -26,10 +26,6 @@ DELETE FROM test.regular_tbl WHERE id = del_count; SET del_count = del_count - 2; END WHILE; END| -Warnings: -Level Warning -Code 1287 -Message ' INTO FROM...' instead CALL test.proc_norm(); connection slave; connection master; diff --git a/mysql-test/suite/rpl/r/rpl_insert_delayed,stmt.rdiff b/mysql-test/suite/rpl/r/rpl_insert_delayed,stmt.rdiff index 1946228f401..d1a101e51ca 100644 --- a/mysql-test/suite/rpl/r/rpl_insert_delayed,stmt.rdiff +++ b/mysql-test/suite/rpl/r/rpl_insert_delayed,stmt.rdiff @@ -1,5 +1,5 @@ ---- suite/rpl/r/rpl_insert_delayed.result 2016-03-25 19:44:43.408210896 +0400 -+++ suite/rpl/r/rpl_insert_delayed,stmt.reject 2016-03-25 23:55:18.396360848 +0400 +--- suite/rpl/r/rpl_insert_delayed.result ++++ suite/rpl/r/rpl_insert_delayed,stmt.reject @@ -18,19 +18,19 @@ insert delayed into t1 values(10, "my name"); flush table t1; diff --git a/mysql-test/suite/rpl/r/rpl_iodku,stmt.rdiff b/mysql-test/suite/rpl/r/rpl_iodku,stmt.rdiff index e31f1e5d991..2986a47c9ae 100644 --- a/mysql-test/suite/rpl/r/rpl_iodku,stmt.rdiff +++ b/mysql-test/suite/rpl/r/rpl_iodku,stmt.rdiff @@ -1,5 +1,5 @@ ---- r/rpl_iodku.result 2022-05-04 18:51:24.956414404 +0300 -+++ r/rpl_iodku,stmt.reject 2022-05-04 18:51:49.520106231 +0300 +--- r/rpl_iodku.result ++++ r/rpl_iodku,stmt.reject @@ -1,10 +1,15 @@ include/master-slave.inc [connection master] diff --git a/mysql-test/suite/rpl/r/rpl_mdev12179.result b/mysql-test/suite/rpl/r/rpl_mdev12179.result index dcda036cdfb..7cb750dd71c 100644 --- a/mysql-test/suite/rpl/r/rpl_mdev12179.result +++ b/mysql-test/suite/rpl/r/rpl_mdev12179.result @@ -259,8 +259,6 @@ connection server_2; *** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery *** connection server_2; SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no; -Warnings: -Warning 1287 ' INTO FROM...' instead connection server_1; INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2; include/save_master_gtid.inc diff --git a/mysql-test/suite/rpl/r/rpl_misc_functions.result b/mysql-test/suite/rpl/r/rpl_misc_functions.result index 302cf2351c2..6c20623d62b 100644 --- a/mysql-test/suite/rpl/r/rpl_misc_functions.result +++ b/mysql-test/suite/rpl/r/rpl_misc_functions.result @@ -42,8 +42,6 @@ INSERT INTO t1 (col_a) VALUES (test_replication_sf()); INSERT INTO t1 (col_a) VALUES (test_replication_sf()); connection slave; select * from t1 into outfile "../../tmp/t1_slave.txt"; -Warnings: -Warning 1287 ' INTO FROM...' instead connection master; create temporary table t1_slave select * from t1 where 1=0; load data infile '../../tmp/t1_slave.txt' into table t1_slave; diff --git a/mysql-test/suite/rpl/r/rpl_row_big_table_id,32bit.rdiff b/mysql-test/suite/rpl/r/rpl_row_big_table_id,32bit.rdiff index 3815ec9375d..1154f92c39e 100644 --- a/mysql-test/suite/rpl/r/rpl_row_big_table_id,32bit.rdiff +++ b/mysql-test/suite/rpl/r/rpl_row_big_table_id,32bit.rdiff @@ -1,5 +1,5 @@ ---- /home/my/maria-test/mysql-test/suite/rpl/r/rpl_row_big_table_id.result 2019-08-18 15:19:56.829962449 +0300 -+++ /home/my/maria-test/mysql-test/suite/rpl/r/rpl_row_big_table_id,32bit.reject 2019-08-18 15:20:19.253763968 +0300 +--- /home/my/maria-test/mysql-test/suite/rpl/r/rpl_row_big_table_id.result ++++ /home/my/maria-test/mysql-test/suite/rpl/r/rpl_row_big_table_id,32bit.reject @@ -20,22 +20,22 @@ master-bin.000001 # Query 1 # use `test`; ALTER TABLE t comment '' master-bin.000001 # Gtid 1 # BEGIN GTID #-#-# diff --git a/mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic,32bit.rdiff b/mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic,32bit.rdiff index c30b99f1f95..77bb1f81d40 100644 --- a/mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/aria_sort_buffer_size_basic.result 2021-02-02 02:58:55.686921205 +0200 -+++ suite/sys_vars/r/aria_sort_buffer_size_basic.reject 2021-02-02 11:02:12.361178360 +0200 +--- suite/sys_vars/r/aria_sort_buffer_size_basic.result ++++ suite/sys_vars/r/aria_sort_buffer_size_basic.reject @@ -44,5 +44,5 @@ set session aria_sort_buffer_size=cast(-1 as unsigned int); select @@session.aria_sort_buffer_size; diff --git a/mysql-test/suite/sys_vars/r/histogram_type_basic.result b/mysql-test/suite/sys_vars/r/histogram_type_basic.result index c24192002aa..8dbd32512f8 100644 --- a/mysql-test/suite/sys_vars/r/histogram_type_basic.result +++ b/mysql-test/suite/sys_vars/r/histogram_type_basic.result @@ -10,7 +10,7 @@ SET @@global.histogram_type = 1; SET @@global.histogram_type = DEFAULT; SELECT @@global.histogram_type; @@global.histogram_type -DOUBLE_PREC_HB +JSON_HB SET @@global.histogram_type = 0; SELECT @@global.histogram_type; @@global.histogram_type diff --git a/mysql-test/suite/sys_vars/r/innodb_fil_make_page_dirty_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_fil_make_page_dirty_debug_basic.result index 477eb7fcb61..abf2cdaf1c4 100644 --- a/mysql-test/suite/sys_vars/r/innodb_fil_make_page_dirty_debug_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_fil_make_page_dirty_debug_basic.result @@ -17,8 +17,6 @@ ERROR HY000: Variable 'innodb_fil_make_page_dirty_debug' is a GLOBAL variable an create table t1 (f1 int primary key) engine = innodb; select space from information_schema.innodb_sys_tables where name = 'test/t1' into @space_id; -Warnings: -Warning 1287 ' INTO FROM...' instead set global innodb_saved_page_number_debug = 0; set global innodb_fil_make_page_dirty_debug = @space_id; drop table t1; diff --git a/mysql-test/suite/sys_vars/r/innodb_ft_result_cache_limit,32bit.rdiff b/mysql-test/suite/sys_vars/r/innodb_ft_result_cache_limit,32bit.rdiff index cd9a004a686..79e15420af3 100644 --- a/mysql-test/suite/sys_vars/r/innodb_ft_result_cache_limit,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/innodb_ft_result_cache_limit,32bit.rdiff @@ -1,5 +1,5 @@ ---- mysql-test/suite/sys_vars/r/innodb_ft_result_cache_limit.result 2019-05-07 15:09:57.220599318 +0530 -+++ mysql-test/suite/sys_vars/r/innodb_ft_result_cache_limit.reject 2019-05-07 15:10:20.012718538 +0530 +--- mysql-test/suite/sys_vars/r/innodb_ft_result_cache_limit.result ++++ mysql-test/suite/sys_vars/r/innodb_ft_result_cache_limit.reject @@ -1,5 +1,7 @@ set global innodb_ft_result_cache_limit=5000000000; +Warnings: diff --git a/mysql-test/suite/sys_vars/r/innodb_saved_page_number_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_saved_page_number_debug_basic.result index b306749dcb0..20e2b78e640 100644 --- a/mysql-test/suite/sys_vars/r/innodb_saved_page_number_debug_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_saved_page_number_debug_basic.result @@ -17,8 +17,6 @@ ERROR HY000: Variable 'innodb_saved_page_number_debug' is a GLOBAL variable and create table t1 (f1 int primary key) engine = innodb; select space from information_schema.innodb_sys_tables where name = 'test/t1' into @space_id; -Warnings: -Warning 1287 ' INTO FROM...' instead set global innodb_saved_page_number_debug = 0; set global innodb_fil_make_page_dirty_debug = @space_id; drop table t1; diff --git a/mysql-test/suite/sys_vars/r/max_join_size_basic.result b/mysql-test/suite/sys_vars/r/max_join_size_basic.result index b87de2bc45e..784d0d0f274 100644 --- a/mysql-test/suite/sys_vars/r/max_join_size_basic.result +++ b/mysql-test/suite/sys_vars/r/max_join_size_basic.result @@ -21,25 +21,25 @@ select * from information_schema.session_variables where variable_name='max_join VARIABLE_NAME VARIABLE_VALUE MAX_JOIN_SIZE 18446744073709551615 set global max_join_size=10; -set session max_join_size=20; +set session max_join_size=100; select @@global.max_join_size; @@global.max_join_size 10 select @@session.max_join_size; @@session.max_join_size -20 +100 show global variables like 'max_join_size'; Variable_name Value max_join_size 10 show session variables like 'max_join_size'; Variable_name Value -max_join_size 20 +max_join_size 100 select * from information_schema.global_variables where variable_name='max_join_size'; VARIABLE_NAME VARIABLE_VALUE MAX_JOIN_SIZE 10 select * from information_schema.session_variables where variable_name='max_join_size'; VARIABLE_NAME VARIABLE_VALUE -MAX_JOIN_SIZE 20 +MAX_JOIN_SIZE 100 set global max_join_size=1.1; ERROR 42000: Incorrect argument type to variable 'max_join_size' set global max_join_size=1e1; diff --git a/mysql-test/suite/sys_vars/r/max_join_size_func.result b/mysql-test/suite/sys_vars/r/max_join_size_func.result index cacc918ea02..d46b89d1f44 100644 --- a/mysql-test/suite/sys_vars/r/max_join_size_func.result +++ b/mysql-test/suite/sys_vars/r/max_join_size_func.result @@ -39,19 +39,19 @@ id name id name connect test_con1, localhost, root,,; connection test_con1; ## Setting value of max_join_size ## -SET @@session.max_join_size=8; +SET @@session.max_join_size=4; ## Since total joins are more than max_join_size value so error will occur ## SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id; ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay '#--------------------FN_DYNVARS_079_03-------------------------#' ## Setting global value of variable ## -SET @@global.max_join_size=8; +SET @@global.max_join_size=4; connect test_con2, localhost, root,,; connection test_con2; ## Verifying value of max_join_size ## SELECT @@global.max_join_size; @@global.max_join_size -8 +4 ## Since total joins are more than max_join_size value so error will occur ## SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id; ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay diff --git a/mysql-test/suite/sys_vars/r/secure_file_priv.result b/mysql-test/suite/sys_vars/r/secure_file_priv.result index 74f816df59d..eeeb9a58c0f 100644 --- a/mysql-test/suite/sys_vars/r/secure_file_priv.result +++ b/mysql-test/suite/sys_vars/r/secure_file_priv.result @@ -6,8 +6,6 @@ INSERT INTO t1 VALUES ("one"),("two"),("three"),("four"),("five"); SHOW VARIABLES LIKE 'secure_file_priv'; Variable_name Value secure_file_priv -Warnings: -Warning 1287 ' INTO FROM...' instead c1 one two diff --git a/mysql-test/suite/sys_vars/r/sql_big_selects_func.result b/mysql-test/suite/sys_vars/r/sql_big_selects_func.result index 609401c771c..104103f681e 100644 --- a/mysql-test/suite/sys_vars/r/sql_big_selects_func.result +++ b/mysql-test/suite/sys_vars/r/sql_big_selects_func.result @@ -3,7 +3,7 @@ SET @session_sql_big_selects = @@SESSION.sql_big_selects; SET @session_max_join_size = @@SESSION.max_join_size; SET @global_max_join_size = @@GLOBAL.max_join_size; -SET MAX_JOIN_SIZE=9; +SET MAX_JOIN_SIZE=21; CREATE TEMPORARY TABLE t1(a varchar(20) not null, b varchar(20)); CREATE TEMPORARY TABLE t2(a varchar(20) null, b varchar(20)); INSERT INTO t1 VALUES('aa','bb'); diff --git a/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff index f0cbbd874ee..3ebce38219c 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_aria.result 2021-02-02 02:58:55.686921205 +0200 -+++ suite/sys_vars/r/sysvars_aria,32bit.reject 2021-02-02 10:55:53.876791633 +0200 +--- suite/sys_vars/r/sysvars_aria.result ++++ suite/sys_vars/r/sysvars_aria,32bit.reject @@ -5,7 +5,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 8192 diff --git a/mysql-test/suite/sys_vars/r/sysvars_debug,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_debug,32bit.rdiff index 8adb294db00..cb8338d4e9b 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_debug,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_debug,32bit.rdiff @@ -1,5 +1,5 @@ ---- r\sysvars_debug.result 2017-08-08 10:52:39.036804900 +0300 -+++ r\sysvars_debug,32bit.reject 2017-09-10 08:06:38.447122100 +0300 +--- r\sysvars_debug.result ++++ r\sysvars_debug,32bit.reject @@ -21,7 +21,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE 0 diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index aa3cc62edab..b9a333afeae 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -2292,6 +2292,26 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_DISK_READ_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of reading a block of IO_SIZE (4096) from a disk (in usec). +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 10000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_DISK_READ_RATIO +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Chance that we have to do a disk read to find a row or index entry from the engine cache (cache_misses/total_cache_requests). 0.0 means that everything is cached and 1.0 means that nothing is expected to be in the engine cache. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_EXTRA_PRUNING_DEPTH VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED @@ -2302,6 +2322,56 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_INDEX_BLOCK_COPY_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of copying a key block from the cache to intern storage as part of an index scan. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_KEY_COMPARE_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of checking a key against the end key condition. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_KEY_COPY_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of finding the next key in the engine and copying it to the SQL layer. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_KEY_LOOKUP_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost for finding a key based on a key value +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_KEY_NEXT_FIND_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of finding the next key and rowid when using filters. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARG_WEIGHT VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED @@ -2322,6 +2392,66 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROWID_COMPARE_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of comparing two rowid's +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROWID_COPY_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of copying a rowid +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROW_COPY_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of copying a row from the engine or the join cache to the SQL layer. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROW_LOOKUP_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of finding a row based on a rowid or a clustered key. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROW_NEXT_FIND_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of finding the next row when scanning the table. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_SCAN_SETUP_COST +VARIABLE_SCOPE SESSION +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Extra cost added to TABLE and INDEX scans to get optimizer to prefer index lookups. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 100000000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SEARCH_DEPTH VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED @@ -2382,6 +2512,16 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_WHERE_COST +VARIABLE_SCOPE SESSION +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of checking the row against the WHERE clause. Increasing this will have the optimizer to prefer plans with less row combinations. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 100000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BOOLEAN diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index e3328521395..075c1ba959a 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -2462,6 +2462,26 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_DISK_READ_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of reading a block of IO_SIZE (4096) from a disk (in usec). +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 10000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_DISK_READ_RATIO +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Chance that we have to do a disk read to find a row or index entry from the engine cache (cache_misses/total_cache_requests). 0.0 means that everything is cached and 1.0 means that nothing is expected to be in the engine cache. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_EXTRA_PRUNING_DEPTH VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED @@ -2472,6 +2492,56 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_INDEX_BLOCK_COPY_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of copying a key block from the cache to intern storage as part of an index scan. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_KEY_COMPARE_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of checking a key against the end key condition. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_KEY_COPY_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of finding the next key in the engine and copying it to the SQL layer. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_KEY_LOOKUP_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost for finding a key based on a key value +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_KEY_NEXT_FIND_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of finding the next key and rowid when using filters. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARG_WEIGHT VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED @@ -2492,6 +2562,66 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROWID_COMPARE_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of comparing two rowid's +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROWID_COPY_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of copying a rowid +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROW_COPY_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of copying a row from the engine or the join cache to the SQL layer. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROW_LOOKUP_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of finding a row based on a rowid or a clustered key. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ROW_NEXT_FIND_COST +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of finding the next row when scanning the table. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 1000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_SCAN_SETUP_COST +VARIABLE_SCOPE SESSION +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Extra cost added to TABLE and INDEX scans to get optimizer to prefer index lookups. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 100000000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SEARCH_DEPTH VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED @@ -2552,6 +2682,16 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_WHERE_COST +VARIABLE_SCOPE SESSION +VARIABLE_TYPE DOUBLE +VARIABLE_COMMENT Cost of checking the row against the WHERE clause. Increasing this will have the optimizer to prefer plans with less row combinations. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 100000 +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BOOLEAN diff --git a/mysql-test/suite/sys_vars/r/sysvars_star.result b/mysql-test/suite/sys_vars/r/sysvars_star.result index b3357fda3af..65a391828b2 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_star.result +++ b/mysql-test/suite/sys_vars/r/sysvars_star.result @@ -60,7 +60,7 @@ VARIABLE_NAME PLUGIN_MATURITY SESSION_VALUE NULL GLOBAL_VALUE alpha GLOBAL_VALUE_ORIGIN CONFIG -DEFAULT_VALUE beta +DEFAULT_VALUE experimental VARIABLE_SCOPE GLOBAL VARIABLE_TYPE ENUM VARIABLE_COMMENT The lowest desirable plugin maturity. Plugins less mature than that will not be installed or loaded diff --git a/mysql-test/suite/sys_vars/r/sysvars_wsrep,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_wsrep,32bit.rdiff index 016bd016f29..73b788057cb 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_wsrep,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_wsrep,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_wsrep.result 2014-10-10 13:33:55.000000000 +0300 -+++ suite/sys_vars/r/sysvars_wsrep,32bit.reject 2014-10-10 19:38:09.000000000 +0300 +--- suite/sys_vars/r/sysvars_wsrep.result ++++ suite/sys_vars/r/sysvars_wsrep,32bit.reject @@ -245,7 +245,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 131072 diff --git a/mysql-test/suite/sys_vars/t/max_join_size_basic.test b/mysql-test/suite/sys_vars/t/max_join_size_basic.test index bbe13457ee7..1741857d6ca 100644 --- a/mysql-test/suite/sys_vars/t/max_join_size_basic.test +++ b/mysql-test/suite/sys_vars/t/max_join_size_basic.test @@ -23,7 +23,7 @@ select * from information_schema.session_variables where variable_name='max_join # show that it's writable # set global max_join_size=10; -set session max_join_size=20; +set session max_join_size=100; select @@global.max_join_size; select @@session.max_join_size; show global variables like 'max_join_size'; diff --git a/mysql-test/suite/sys_vars/t/max_join_size_func.test b/mysql-test/suite/sys_vars/t/max_join_size_func.test index c649c036565..5fc8ee5855b 100644 --- a/mysql-test/suite/sys_vars/t/max_join_size_func.test +++ b/mysql-test/suite/sys_vars/t/max_join_size_func.test @@ -84,7 +84,7 @@ connect (test_con1, localhost, root,,); connection test_con1; --echo ## Setting value of max_join_size ## -SET @@session.max_join_size=8; +SET @@session.max_join_size=4; --echo ## Since total joins are more than max_join_size value so error will occur ## --Error ER_TOO_BIG_SELECT @@ -97,7 +97,7 @@ SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id; ########################################################## --echo ## Setting global value of variable ## -SET @@global.max_join_size=8; +SET @@global.max_join_size=4; connect (test_con2, localhost, root,,); connection test_con2; diff --git a/mysql-test/suite/sys_vars/t/sql_big_selects_func.test b/mysql-test/suite/sys_vars/t/sql_big_selects_func.test index 59d8184861d..b8ff7c53f75 100644 --- a/mysql-test/suite/sys_vars/t/sql_big_selects_func.test +++ b/mysql-test/suite/sys_vars/t/sql_big_selects_func.test @@ -28,7 +28,7 @@ SET @session_sql_big_selects = @@SESSION.sql_big_selects; SET @session_max_join_size = @@SESSION.max_join_size; SET @global_max_join_size = @@GLOBAL.max_join_size; -SET MAX_JOIN_SIZE=9; +SET MAX_JOIN_SIZE=21; # # Create tables @@ -115,8 +115,6 @@ disconnect con_int2; # # Cleanup # - - SET @@SESSION.sql_big_selects = @session_sql_big_selects; SET @@SESSION.max_join_size = @session_max_join_size; SET @@GLOBAL.max_join_size = @global_max_join_size; diff --git a/mysql-test/suite/sysschema/r/all_sys_objects_exist.result b/mysql-test/suite/sysschema/r/all_sys_objects_exist.result index 6dddd8a186c..4c1bf311450 100644 --- a/mysql-test/suite/sysschema/r/all_sys_objects_exist.result +++ b/mysql-test/suite/sysschema/r/all_sys_objects_exist.result @@ -129,6 +129,9 @@ version_patch FUNCTION create_synonym_db PROCEDURE diagnostics PROCEDURE execute_prepared_stmt PROCEDURE +optimizer_switch_choice PROCEDURE +optimizer_switch_off PROCEDURE +optimizer_switch_on PROCEDURE ps_setup_disable_background_threads PROCEDURE ps_setup_disable_consumer PROCEDURE ps_setup_disable_instrument PROCEDURE diff --git a/mysql-test/suite/sysschema/r/optimizer_switch.result b/mysql-test/suite/sysschema/r/optimizer_switch.result new file mode 100644 index 00000000000..017276fc4b8 --- /dev/null +++ b/mysql-test/suite/sysschema/r/optimizer_switch.result @@ -0,0 +1,40 @@ +call sys.optimizer_switch_on(); +option opt +condition_pushdown_for_derived on +condition_pushdown_for_subquery on +condition_pushdown_from_having on +derived_merge on +derived_with_keys on +exists_to_in on +extended_keys on +firstmatch on +index_condition_pushdown on +index_merge on +index_merge_intersection on +index_merge_sort_union on +index_merge_union on +in_to_exists on +join_cache_bka on +join_cache_hashed on +join_cache_incremental on +loosescan on +materialization on +optimize_join_buffer_size on +orderby_uses_equalities on +outer_join_with_cache on +partial_match_rowid_merge on +partial_match_table_scan on +rowid_filter on +semijoin on +semijoin_with_cache on +split_materialized on +subquery_cache on +table_elimination on +call sys.optimizer_switch_off(); +option opt +engine_condition_pushdown off +index_merge_sort_intersection off +mrr off +mrr_cost_based off +mrr_sort_keys off +not_null_range_scan off diff --git a/mysql-test/suite/sysschema/r/v_schema_redundant_indexes.result b/mysql-test/suite/sysschema/r/v_schema_redundant_indexes.result index 2199c959cd0..8893726fe12 100644 --- a/mysql-test/suite/sysschema/r/v_schema_redundant_indexes.result +++ b/mysql-test/suite/sysschema/r/v_schema_redundant_indexes.result @@ -32,6 +32,6 @@ KEY (i, j, k) ); SELECT * FROM sys.schema_redundant_indexes; table_schema table_name redundant_index_name redundant_index_columns redundant_index_non_unique dominant_index_name dominant_index_columns dominant_index_non_unique subpart_exists sql_drop_index -rkey rkey j j 1 j_2 j,k 1 0 ALTER TABLE `rkey`.`rkey` DROP INDEX `j` rkey rkey i i,j,k 1 PRIMARY i 0 0 ALTER TABLE `rkey`.`rkey` DROP INDEX `i` +rkey rkey j j 1 j_2 j,k 1 0 ALTER TABLE `rkey`.`rkey` DROP INDEX `j` DROP DATABASE rkey; diff --git a/mysql-test/suite/sysschema/t/optimizer_switch.test b/mysql-test/suite/sysschema/t/optimizer_switch.test new file mode 100644 index 00000000000..b4d527e5519 --- /dev/null +++ b/mysql-test/suite/sysschema/t/optimizer_switch.test @@ -0,0 +1,2 @@ +call sys.optimizer_switch_on(); +call sys.optimizer_switch_off(); diff --git a/mysql-test/suite/sysschema/t/pr_statement_performance_analyzer.test b/mysql-test/suite/sysschema/t/pr_statement_performance_analyzer.test index b8932381e52..96b59a55e6d 100644 --- a/mysql-test/suite/sysschema/t/pr_statement_performance_analyzer.test +++ b/mysql-test/suite/sysschema/t/pr_statement_performance_analyzer.test @@ -155,9 +155,10 @@ CALL sys.statement_performance_analyzer('delta', 'test.tmp_digests_ini', 'analys CALL sys.statement_performance_analyzer('overall', NULL, 'with_errors_or_warnings'); CALL sys.statement_performance_analyzer('delta', 'test.tmp_digests_ini', 'with_errors_or_warnings'); ---replace_result $query_select QUERY_SELECT $digest_select DIGEST_SELECT $o_sel_total_latency LATENCY $o_sel_first_seen FIRST_SEEN $o_sel_last_seen LAST_SEEN +--replace_column 4 LATENCY +--replace_result $query_select QUERY_SELECT $digest_select DIGEST_SELECT $o_sel_first_seen FIRST_SEEN $o_sel_last_seen LAST_SEEN $digest_update DIGEST_UPDATE $query_update QUERY_UPDATE $o_upd_first_seen FIRST_SEEN $o_upd_last_seen LAST_SEEN CALL sys.statement_performance_analyzer('overall', NULL, 'with_full_table_scans'); ---replace_result $query_select QUERY_SELECT $digest_select DIGEST_SELECT $d_sel_total_latency LATENCY $o_sel_first_seen FIRST_SEEN $o_sel_last_seen LAST_SEEN +--replace_result $query_select QUERY_SELECT $digest_select DIGEST_SELECT $d_sel_total_latency LATENCY $o_sel_first_seen FIRST_SEEN $o_sel_last_seen LAST_SEEN CALL sys.statement_performance_analyzer('delta', 'test.tmp_digests_ini', 'with_full_table_scans'); --replace_result $query_select QUERY_SELECT $digest_select DIGEST_SELECT $o_sel_total_latency LATENCY $o_sel_first_seen FIRST_SEEN $o_sel_last_seen LAST_SEEN diff --git a/mysql-test/suite/sysschema/t/v_schema_redundant_indexes.test b/mysql-test/suite/sysschema/t/v_schema_redundant_indexes.test index 0cd2ac91fa4..ed40a294238 100644 --- a/mysql-test/suite/sysschema/t/v_schema_redundant_indexes.test +++ b/mysql-test/suite/sysschema/t/v_schema_redundant_indexes.test @@ -34,6 +34,7 @@ CREATE TABLE rkey.rkey ( KEY (i, j, k) ); +--sorted_result SELECT * FROM sys.schema_redundant_indexes; DROP DATABASE rkey; diff --git a/mysql-test/suite/vcol/inc/vcol_ins_upd.inc b/mysql-test/suite/vcol/inc/vcol_ins_upd.inc index 8cf0fb9ed6c..c523083d370 100644 --- a/mysql-test/suite/vcol/inc/vcol_ins_upd.inc +++ b/mysql-test/suite/vcol/inc/vcol_ins_upd.inc @@ -29,6 +29,8 @@ let $create4 = create table t1 (a int, d varchar(16)); eval $create1; set sql_warnings = 1; +# Prefer table scans to range +set @@optimizer_scan_setup_cost=0; --echo # --echo # *** INSERT *** @@ -197,6 +199,7 @@ select * from t1; --echo # UPDATE tbl_name SET non-vcol=expr --echo # WHERE vcol=between const1 and const2 ORDER BY vcol LIMIT 2 insert into t1 (a) values (1), (2), (3), (4), (5); + select * from t1; update t1 set a=6 where c between -1 and 0 order by c limit 2; diff --git a/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result index 6807f89fdbe..624477d20f0 100644 --- a/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result @@ -3,6 +3,7 @@ create table t1 (a int, b int as (-a), c int as (-a) persistent); set sql_warnings = 1; +set @@optimizer_scan_setup_cost=0; # # *** INSERT *** # diff --git a/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result index 43206dba31b..823b4f520e6 100644 --- a/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result @@ -3,6 +3,7 @@ create table t1 (a int, b int as (-a), c int as (-a) persistent); set sql_warnings = 1; +set @@optimizer_scan_setup_cost=0; # # *** INSERT *** # diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result index 40308b6e072..57a17cbe468 100644 --- a/mysql-test/suite/vcol/r/vcol_select_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result @@ -135,7 +135,7 @@ count(distinct c) 3 explain select count(distinct c) from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL c 5 NULL 6 Using index for group-by +1 SIMPLE t1 range NULL c 5 NULL 5 Using index for group-by ### ### filesort & range-based utils ### diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result index 05f86347706..8964eda1ba8 100644 --- a/mysql-test/suite/vcol/r/vcol_select_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result @@ -74,7 +74,7 @@ a b c explain select * from t1 where c in (select c from t3 where c between -2 and -1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 range c c 5 NULL 2 Using where; Using index -1 PRIMARY t1 ref c c 5 test.t3.c 2 +1 PRIMARY t1 ref c c 5 test.t3.c 1 # select_type=UNION, type=system # select_type=UNION RESULT, type= select * from t1 union select * from t2; @@ -133,7 +133,7 @@ count(distinct c) 3 explain select count(distinct c) from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL c 5 NULL 6 Using index for group-by +1 SIMPLE t1 range NULL c 5 NULL 5 Using index for group-by ### ### filesort & range-based utils ### diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index 9751f7c718d..7f7323ba47f 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -199,8 +199,6 @@ a 2 1 select row_start from t where a=3 into @tm; -Warnings: -Warning 1287 ' INTO FROM...' instead alter table t add column b int; select @tm=row_start from t where a=3; @tm=row_start diff --git a/mysql-test/suite/versioning/r/commit_id.result b/mysql-test/suite/versioning/r/commit_id.result index 8815613292e..abf2eaf91ba 100644 --- a/mysql-test/suite/versioning/r/commit_id.result +++ b/mysql-test/suite/versioning/r/commit_id.result @@ -10,8 +10,6 @@ insert into t1 values (); set @ts0= now(6); insert into t1 values (); select sys_trx_start from t1 where id = last_insert_id() into @tx0; -Warnings: -Warning 1287 ' INTO FROM...' instead select transaction_id = @tx0 from mysql.transaction_registry order by transaction_id desc limit 1; transaction_id = @tx0 @@ -19,8 +17,6 @@ transaction_id = @tx0 set @ts1= now(6); insert into t1 values (); select sys_trx_start from t1 where id = last_insert_id() into @tx1; -Warnings: -Warning 1287 ' INTO FROM...' instead select transaction_id = @tx1 from mysql.transaction_registry order by transaction_id desc limit 1; transaction_id = @tx1 @@ -28,8 +24,6 @@ transaction_id = @tx1 set @ts2= now(6); insert into t1 values (); select sys_trx_start from t1 where id = last_insert_id() into @tx2; -Warnings: -Warning 1287 ' INTO FROM...' instead select transaction_id = @tx2 from mysql.transaction_registry order by transaction_id desc limit 1; transaction_id = @tx2 @@ -72,32 +66,24 @@ trt_trx_sees(0, @tx2) set transaction isolation level read uncommitted; insert into t1 values (); select sys_trx_start from t1 where id = last_insert_id() into @tx3; -Warnings: -Warning 1287 ' INTO FROM...' instead select isolation_level = 'READ-UNCOMMITTED' from mysql.transaction_registry where transaction_id = @tx3; isolation_level = 'READ-UNCOMMITTED' 1 set transaction isolation level read committed; insert into t1 values (); select sys_trx_start from t1 where id = last_insert_id() into @tx4; -Warnings: -Warning 1287 ' INTO FROM...' instead select isolation_level = 'READ-COMMITTED' from mysql.transaction_registry where transaction_id = @tx4; isolation_level = 'READ-COMMITTED' 1 set transaction isolation level serializable; insert into t1 values (); select sys_trx_start from t1 where id = last_insert_id() into @tx5; -Warnings: -Warning 1287 ' INTO FROM...' instead select isolation_level = 'SERIALIZABLE' from mysql.transaction_registry where transaction_id = @tx5; isolation_level = 'SERIALIZABLE' 1 set transaction isolation level repeatable read; insert into t1 values (); select sys_trx_start from t1 where id = last_insert_id() into @tx6; -Warnings: -Warning 1287 ' INTO FROM...' instead select isolation_level = 'REPEATABLE-READ' from mysql.transaction_registry where transaction_id = @tx6; isolation_level = 'REPEATABLE-READ' 1 diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result index c9d68f15e57..158f0b7faf3 100644 --- a/mysql-test/suite/versioning/r/create.result +++ b/mysql-test/suite/versioning/r/create.result @@ -271,12 +271,8 @@ t3 CREATE TABLE `t3` ( ## For versioned table insert into t1 values (1); select row_start from t1 into @row_start; -Warnings: -Warning 1287 ' INTO FROM...' instead insert into t0 (y) values (2); select st from t0 into @st; -Warnings: -Warning 1287 ' INTO FROM...' instead create or replace table t2 with system versioning as select * from t1; show create table t2; Table Create Table @@ -339,12 +335,8 @@ ERROR 42S21: Duplicate column name 'row_end' # Prepare checking for historical row delete from t1; select row_end from t1 for system_time all into @row_end; -Warnings: -Warning 1287 ' INTO FROM...' instead delete from t0; select en from t0 for system_time all into @en; -Warnings: -Warning 1287 ' INTO FROM...' instead ## Combinations of versioned + non-versioned create or replace table t2 (y int); insert into t2 values (3); @@ -365,14 +357,10 @@ insert into t2 (y) values (1), (2); delete from t2 where y = 2; create or replace table t3 select * from t2 for system_time all; select st, en from t3 where y = 1 into @st, @en; -Warnings: -Warning 1287 ' INTO FROM...' instead select y from t2 for system_time all where st = @st and en = @en; y 1 select st, en from t3 where y = 2 into @st, @en; -Warnings: -Warning 1287 ' INTO FROM...' instead select y from t2 for system_time all where st = @st and en = @en; y 2 diff --git a/mysql-test/suite/versioning/r/cte.result b/mysql-test/suite/versioning/r/cte.result index 6ca9c238d45..11d478ac456 100644 --- a/mysql-test/suite/versioning/r/cte.result +++ b/mysql-test/suite/versioning/r/cte.result @@ -61,7 +61,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY ALL NULL NULL NULL NULL 4 100.00 2 DERIVED e ALL NULL NULL NULL NULL 4 100.00 Using where 3 RECURSIVE UNION e ALL mgr-fk NULL NULL NULL 4 100.00 Using where -3 RECURSIVE UNION ref key0 key0 5 test.e.mgr 2 100.00 +3 RECURSIVE UNION ref key0 key0 5 test.e.mgr 1 100.00 NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors` @@ -102,7 +102,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY ALL NULL NULL NULL NULL 4 100.00 2 DERIVED e ALL NULL NULL NULL NULL 4 100.00 Using where 3 RECURSIVE UNION e ALL mgr-fk NULL NULL NULL 4 100.00 Using where -3 RECURSIVE UNION ref key0 key0 5 test.e.mgr 2 100.00 +3 RECURSIVE UNION ref key0 key0 5 test.e.mgr 1 100.00 NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors` @@ -140,10 +140,10 @@ where e.mgr = a.emp_id select name from emp where emp_id in (select emp_id from ancestors for system_time as of timestamp @ts_1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY emp ALL PRIMARY NULL NULL NULL 4 100.00 Using where -1 PRIMARY ref key0 key0 5 test.emp.emp_id 2 100.00 FirstMatch(emp) +1 PRIMARY ref key0 key0 5 test.emp.emp_id 1 100.00 FirstMatch(emp) 2 DERIVED e ALL NULL NULL NULL NULL 4 100.00 Using where 3 RECURSIVE UNION e ALL mgr-fk NULL NULL NULL 4 100.00 Using where -3 RECURSIVE UNION ref key0 key0 5 test.e.mgr 2 100.00 +3 RECURSIVE UNION ref key0 key0 5 test.e.mgr 1 100.00 NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `test`.`emp`.`name` AS `name` from `test`.`emp` semi join (`ancestors`) where `ancestors`.`emp_id` = `test`.`emp`.`emp_id` and `test`.`emp`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result index b17deba1c1e..7c8d9577096 100644 --- a/mysql-test/suite/versioning/r/foreign.result +++ b/mysql-test/suite/versioning/r/foreign.result @@ -274,8 +274,6 @@ on update cascade ) engine=innodb; insert into parent (value) values (23); select id, value from parent into @id, @value; -Warnings: -Warning 1287 ' INTO FROM...' instead insert into child values (default, @id, @value); insert into subchild values (default, @id, @value); select parent_id from subchild; diff --git a/mysql-test/suite/versioning/r/insert.result b/mysql-test/suite/versioning/r/insert.result index 442d71c6a91..fab71b9f1cc 100644 --- a/mysql-test/suite/versioning/r/insert.result +++ b/mysql-test/suite/versioning/r/insert.result @@ -54,8 +54,6 @@ drop view vt1_1; create or replace table t1( id bigint primary key, a int, b int) with system versioning; insert into t1 values(1, 1, 1); select row_start, row_end from t1 into @sys_start, @sys_end; -Warnings: -Warning 1287 ' INTO FROM...' instead select id, a, b from t1; id a b 1 1 1 diff --git a/mysql-test/suite/versioning/r/load_data.result b/mysql-test/suite/versioning/r/load_data.result index 1fcde73e565..5e7b36c9a6a 100644 --- a/mysql-test/suite/versioning/r/load_data.result +++ b/mysql-test/suite/versioning/r/load_data.result @@ -1,8 +1,6 @@ CREATE TABLE t1 (a INT, b INT, c INT, vc INT AS (c), UNIQUE(a), UNIQUE(b)) WITH SYSTEM VERSIONING; INSERT IGNORE INTO t1 (a,b,c) VALUES (1,2,3); SELECT a, b, c FROM t1 INTO OUTFILE '15330.data'; -Warnings: -Warning 1287 ' INTO FROM...' instead LOAD DATA INFILE '15330.data' IGNORE INTO TABLE t1 (a,b,c); Warnings: Warning 1062 Duplicate entry '1' for key 'a' diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index febb19bf48e..3656db2fe06 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -178,8 +178,6 @@ x C D 1 1 1 set @str= concat('select row_start from t1 partition (pn) into @ts0'); prepare stmt from @str; -Warnings: -Warning 1287 ' INTO FROM...' instead execute stmt; drop prepare stmt; set @now= now(6); @@ -191,8 +189,6 @@ execute select_pn; x C D set @str= concat('select row_start from t1 partition (p0) into @ts1'); prepare stmt from @str; -Warnings: -Warning 1287 ' INTO FROM...' instead execute stmt; drop prepare stmt; select @ts0 = @ts1; @@ -208,8 +204,6 @@ x C D 2 1 1 set @str= concat('select row_start from t1 partition (pn) into @ts0'); prepare stmt from @str; -Warnings: -Warning 1287 ' INTO FROM...' instead execute stmt; drop prepare stmt; set @now= now(6); @@ -225,20 +219,14 @@ drop prepare select_p0; drop prepare select_pn; set @str= concat('select row_start from t1 partition (p0) where x = 2 into @ts1'); prepare stmt from @str; -Warnings: -Warning 1287 ' INTO FROM...' instead execute stmt; drop prepare stmt; set @str= concat('select row_end from t1 partition (p0) where x = 2 into @ts2'); prepare stmt from @str; -Warnings: -Warning 1287 ' INTO FROM...' instead execute stmt; drop prepare stmt; set @str= concat('select row_start from t1 partition (pn) into @ts3'); prepare stmt from @str; -Warnings: -Warning 1287 ' INTO FROM...' instead execute stmt; drop prepare stmt; select @ts0 = @ts1; @@ -821,8 +809,6 @@ create or replace table t2 (f int); create or replace trigger tr before insert on t2 for each row select table_rows from information_schema.tables where table_name = 't1' into @a; -Warnings: -Warning 1287 ' INTO FROM...' instead insert into t2 values (1); # # MDEV-14740 Locking assertion for system_time partitioning @@ -832,8 +818,6 @@ partition by system_time interval 1 week; create or replace table t2 (f int); create or replace trigger tr before insert on t2 for each row select count(*) from t1 into @a; -Warnings: -Warning 1287 ' INTO FROM...' instead insert into t2 values (1); # # MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES diff --git a/mysql-test/suite/versioning/r/select,trx_id.rdiff b/mysql-test/suite/versioning/r/select,trx_id.rdiff deleted file mode 100644 index 8906007a348..00000000000 --- a/mysql-test/suite/versioning/r/select,trx_id.rdiff +++ /dev/null @@ -1,11 +0,0 @@ ---- select.result 2018-06-29 18:09:17.962447067 +0200 -+++ select.reject 2018-06-29 18:10:04.618808616 +0200 -@@ -17,6 +17,8 @@ - (8, 108), - (9, 109); - set @t0= now(6); -+Warnings: -+Warning 1287 ' INTO FROM...' instead - delete from t1 where x = 3; - delete from t1 where x > 7; - insert into t1(x, y) values(3, 33); diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 90c99d1bf0e..9841b4dedbb 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -23,8 +23,6 @@ delete from t1 where x = 3; delete from t1 where x > 7; insert into t1(x, y) values(3, 33); select sys_trx_start from t1 where x = 3 and y = 33 into @t1; -Warnings: -Warning 1287 ' INTO FROM...' instead select x, y from t1; x y 0 100 @@ -382,8 +380,6 @@ insert into t1 values (1); set @ts= now(6); delete from t1; select sys_trx_start from t1 for system_time all into @trx_start; -Warnings: -Warning 1287 ' INTO FROM...' instead ## ensure @trx_start is much lower than unix timestamp select @trx_start < unix_timestamp(@ts) - 100 as trx_start_good; trx_start_good @@ -577,11 +573,7 @@ period for system_time (row_start, row_end) insert into t1 values (1); delete from t1; select row_start from t1 for system_time all into @t1; -Warnings: -Warning 1287 ' INTO FROM...' instead select row_end from t1 for system_time all into @t2; -Warnings: -Warning 1287 ' INTO FROM...' instead select * from t1 for system_time between @t1 and @t2; a 1 diff --git a/mysql-test/suite/versioning/r/select2,trx_id.rdiff b/mysql-test/suite/versioning/r/select2,trx_id.rdiff index bdc20d1dc4f..45555385c31 100644 --- a/mysql-test/suite/versioning/r/select2,trx_id.rdiff +++ b/mysql-test/suite/versioning/r/select2,trx_id.rdiff @@ -1,15 +1,15 @@ ---- select2.result 2018-06-29 17:51:17.142172085 +0200 -+++ select2,trx_id.reject 2018-06-29 18:03:49.034273090 +0200 -@@ -26,6 +26,8 @@ +--- suite/versioning/r/select2.result 2022-12-12 19:34:34.242342915 +0200 ++++ suite/versioning/r/select2,trx_id.reject 2022-12-12 19:37:18.721907294 +0200 +@@ -22,6 +22,8 @@ + delete from t1 where x > 7; + insert into t1(x, y) values(3, 33); select sys_start from t1 where x = 3 and y = 33 into @t1; - Warnings: - Warning 1287 ' INTO FROM...' instead +set @x1= @t1; +select trt_commit_ts(@x1) into @t1; select x, y from t1; x y 0 100 -@@ -86,7 +88,7 @@ +@@ -82,7 +84,7 @@ 8 108 9 109 3 33 @@ -18,7 +18,7 @@ ASOF2_x y 0 100 1 101 -@@ -98,7 +100,7 @@ +@@ -94,7 +96,7 @@ 7 107 8 108 9 109 @@ -27,7 +27,7 @@ FROMTO2_x y 0 100 1 101 -@@ -110,7 +112,7 @@ +@@ -106,7 +108,7 @@ 7 107 8 108 9 109 diff --git a/mysql-test/suite/versioning/r/select2.result b/mysql-test/suite/versioning/r/select2.result index 353bdf8e696..613fe86e668 100644 --- a/mysql-test/suite/versioning/r/select2.result +++ b/mysql-test/suite/versioning/r/select2.result @@ -18,14 +18,10 @@ insert into t1 (x, y) values (9, 109); set @t0= now(6); select sys_start from t1 limit 1 into @x0; -Warnings: -Warning 1287 ' INTO FROM...' instead delete from t1 where x = 3; delete from t1 where x > 7; insert into t1(x, y) values(3, 33); select sys_start from t1 where x = 3 and y = 33 into @t1; -Warnings: -Warning 1287 ' INTO FROM...' instead select x, y from t1; x y 0 100 diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result index 9beec414fbb..d9abbe9cc54 100644 --- a/mysql-test/suite/versioning/r/trx_id.result +++ b/mysql-test/suite/versioning/r/trx_id.result @@ -25,15 +25,11 @@ add period for system_time(s, e), add system versioning, algorithm=inplace; select s from t1 into @trx_start; -Warnings: -Warning 1287 ' INTO FROM...' instead select count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start; count(*) = 1 1 create or replace table t1 (x int); select count(*) from mysql.transaction_registry into @tmp; -Warnings: -Warning 1287 ' INTO FROM...' instead alter table t1 add column s bigint unsigned as row start, add column e bigint unsigned as row end, @@ -52,15 +48,11 @@ add period for system_time(s, e), add system versioning, algorithm=copy; select s from t1 into @trx_start; -Warnings: -Warning 1287 ' INTO FROM...' instead select count(*) = 1 from mysql.transaction_registry where transaction_id = @trx_start; count(*) = 1 1 create or replace table t1 (x int); select count(*) from mysql.transaction_registry into @tmp; -Warnings: -Warning 1287 ' INTO FROM...' instead alter table t1 add column s bigint unsigned as row start, add column e bigint unsigned as row end, @@ -113,14 +105,8 @@ set @ts2= sysdate(6); commit; set @ts3= sysdate(6); select sys_start from t1 where x = 1 into @trx_id1; -Warnings: -Warning 1287 ' INTO FROM...' instead select sys_start from t1 where x = 2 into @trx_id2; -Warnings: -Warning 1287 ' INTO FROM...' instead select sys_start from t1 where x = 3 into @trx_id3; -Warnings: -Warning 1287 ' INTO FROM...' instead select @trx_id1 < @trx_id2, @trx_id2 < @trx_id3; @trx_id1 < @trx_id2 @trx_id2 < @trx_id3 1 1 @@ -278,8 +264,6 @@ set @ts1= now(6); insert into t1 values (1); commit; select row_start from t1 into @trx_id; -Warnings: -Warning 1287 ' INTO FROM...' instead select trt_begin_ts(@trx_id) <= @ts1 as BEGIN_TS_GOOD; BEGIN_TS_GOOD 1 diff --git a/mysql-test/suite/versioning/r/update,trx_id.rdiff b/mysql-test/suite/versioning/r/update,trx_id.rdiff index 7ce75714235..5f0e77bf54e 100644 --- a/mysql-test/suite/versioning/r/update,trx_id.rdiff +++ b/mysql-test/suite/versioning/r/update,trx_id.rdiff @@ -1,5 +1,5 @@ ---- update.result 2018-12-19 13:55:35.873917389 +0300 -+++ update,trx_id.reject 2018-12-19 13:55:35.533917399 +0300 +--- update.result ++++ update,trx_id.reject @@ -81,12 +81,10 @@ commit; select x, y, sys_trx_end = MAXVAL as current from t1 for system_time all order by sys_trx_end, x, y; diff --git a/mysql-test/suite/wsrep/r/wsrep-recover-v25,binlogon.rdiff b/mysql-test/suite/wsrep/r/wsrep-recover-v25,binlogon.rdiff index 596abf9c681..5fc091c7752 100644 --- a/mysql-test/suite/wsrep/r/wsrep-recover-v25,binlogon.rdiff +++ b/mysql-test/suite/wsrep/r/wsrep-recover-v25,binlogon.rdiff @@ -1,5 +1,5 @@ ---- r/wsrep-recover-v25.result 2019-02-28 09:20:56.153775856 +0200 -+++ r/wsrep-recover-v25.reject 2019-02-28 09:22:16.578113115 +0200 +--- r/wsrep-recover-v25.result ++++ r/wsrep-recover-v25.reject @@ -12,4 +12,16 @@ SELECT VARIABLE_VALUE `expect 6` FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'; expect 6 diff --git a/mysys/array.c b/mysys/array.c index 6e871ee6343..02a54d44656 100644 --- a/mysys/array.c +++ b/mysys/array.c @@ -92,7 +92,7 @@ my_bool init_dynamic_array2(PSI_memory_key psi_key, DYNAMIC_ARRAY *array, my_bool insert_dynamic(DYNAMIC_ARRAY *array, const void * element) { void *buffer; - if (array->elements == array->max_element) + if (unlikely(array->elements == array->max_element)) { /* Call only when necessary */ if (!(buffer=alloc_dynamic(array))) return TRUE; @@ -102,7 +102,42 @@ my_bool insert_dynamic(DYNAMIC_ARRAY *array, const void * element) buffer=array->buffer+(array->elements * array->size_of_element); array->elements++; } - memcpy(buffer,element,(size_t) array->size_of_element); + memcpy(buffer, element, array->size_of_element); + return FALSE; +} + + +/* Fast version of appending to dynamic array */ + +void init_append_dynamic(DYNAMIC_ARRAY_APPEND *append, + DYNAMIC_ARRAY *array) +{ + append->array= array; + append->pos= array->buffer + array->elements * array->size_of_element; + append->end= array->buffer + array->max_element * array->size_of_element; +} + + +my_bool append_dynamic(DYNAMIC_ARRAY_APPEND *append, + const void *element) +{ + DYNAMIC_ARRAY *array= append->array; + size_t size_of_element= array->size_of_element; + if (unlikely(append->pos == append->end)) + { + void *buffer; + if (!(buffer=alloc_dynamic(array))) + return TRUE; + append->pos= (uchar*)buffer + size_of_element; + append->end= array->buffer + array->max_element * size_of_element; + memcpy(buffer, element, size_of_element); + } + else + { + array->elements++; + memcpy(append->pos, element, size_of_element); + append->pos+= size_of_element; + } return FALSE; } @@ -281,7 +316,7 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, size_t max_elements) void get_dynamic(DYNAMIC_ARRAY *array, void *element, size_t idx) { - if (idx >= array->elements) + if (unlikely(idx >= array->elements)) { DBUG_PRINT("warning",("To big array idx: %d, array size is %d", idx,array->elements)); @@ -306,7 +341,7 @@ void delete_dynamic(DYNAMIC_ARRAY *array) /* Just mark as empty if we are using a static buffer */ - if (!(array->malloc_flags & MY_INIT_BUFFER_USED) && array->buffer) + if (array->buffer && !(array->malloc_flags & MY_INIT_BUFFER_USED)) my_free(array->buffer); array->buffer= 0; diff --git a/mysys/mf_radix.c b/mysys/mf_radix.c index 8f044cf9b29..89a3c4ac6ce 100644 --- a/mysys/mf_radix.c +++ b/mysys/mf_radix.c @@ -26,7 +26,7 @@ /* Radixsort */ -my_bool radixsort_is_appliccable(uint n_items, size_t size_of_element) +my_bool radixsort_is_applicable(uint n_items, size_t size_of_element) { return size_of_element <= 20 && n_items >= 1000 && n_items < 100000; } diff --git a/mysys/mf_sort.c b/mysys/mf_sort.c index 24e875b813e..79bdfdd23aa 100644 --- a/mysys/mf_sort.c +++ b/mysys/mf_sort.c @@ -23,7 +23,7 @@ void my_string_ptr_sort(uchar *base, uint items, size_t size) #if INT_MAX > 65536L uchar **ptr=0; - if (radixsort_is_appliccable(items, size) && + if (radixsort_is_applicable(items, size) && (ptr= (uchar**) my_malloc(PSI_NOT_INSTRUMENTED, items * sizeof(char*),MYF(0)))) { diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 9f13ca7a424..d1b2c599372 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -897,7 +897,9 @@ static int setval(const struct my_option *opts, void *value, char *argument, goto ret; }; } + validate_value(opts->name, argument, option_file); + DBUG_RETURN(0); ret: diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet4.result b/plugin/type_inet/mysql-test/type_inet/type_inet4.result index 7763b28e1fb..30cb6f7fe94 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet4.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet4.result @@ -1337,7 +1337,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM t1 WHERE b IN (SELECT a AS a_inner FROM t1 GROUP BY a_inner); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1 Using index; Using where SET @@optimizer_switch=DEFAULT; DROP TABLE t1; # diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.result b/plugin/type_inet/mysql-test/type_inet/type_inet6.result index 8d52e85cb91..b399400ab87 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.result @@ -1330,7 +1330,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM t1 WHERE b IN (SELECT a AS a_inner FROM t1 GROUP BY a_inner); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t1 index_subquery a a 17 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t1 index_subquery a a 17 func 1 Using index; Using where SET @@optimizer_switch=DEFAULT; DROP TABLE t1; # diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result index ab30c262148..b3955d09735 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result @@ -2524,7 +2524,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM t1 WHERE b IN (SELECT a AS a_inner FROM t1 GROUP BY a_inner); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t1 index_subquery a a 17 func 2 Using index; Using where +2 DEPENDENT SUBQUERY t1 index_subquery a a 17 func 1 Using index; Using where SET @@optimizer_switch=DEFAULT; DROP TABLE t1; # diff --git a/scripts/convert-debug-for-diff.sh b/scripts/convert-debug-for-diff.sh index 5b3ce05b815..4d266a6d526 100755 --- a/scripts/convert-debug-for-diff.sh +++ b/scripts/convert-debug-for-diff.sh @@ -18,8 +18,25 @@ while (<>) { - s/^T@[0-9]+\s*://g; - s/0x[0-9a-f]+(\s|\n|\))/#$1/g; - s/size: [0-9]+/size: #/g; + s/^T@[0-9]+ *://g; + s/0x[0-9a-f]+(\s|\n|\)|=|,|;)/#$1/g; + s/size: [0-9-]+/size: #/g; + s/memory_used: [0-9]+/memory_used: #/g; + s/Total alloc: [0-9]+/Total alloc: #/g; + s/(proc_info: )(.*:)[\d]+ /$1 /; + s/(select_cond.*) at line.*/$1/; + s/\(id: \d+ -> \d+\)/id: #->#/g; + s/(exit: found key at )\d+/$1#/g; + s/enter_stage: ([^\/]*)(\/.*\/)(.*)(:\d+)/enter_stage: ($1)/g; + s/crc: [0-9]+/crc: #/g; + s/ref_count: [0-9]+/ref_count: #/g; + s/block: # \(\d+\)/block: # (#)/g; + s/delete_mutex: # mutex: # \(id: \d+ \<\- \d+\)/delete_mutex: # mutex: # (id: # <- #)/g; + s/ShortTrID: [0-9]+/ShortTrID: #/g; + s/timestamp:[0-9]+/timestamp:#/g; + s/#sql_.*_(\d+)/#sql_xxx_$1/g; + s/fd: [0-9]+/fd: #/g; + s/query_id: (\d+)/query_id: #/g; + s|: .*/mysql-test/var/tmp/mysqld\.\d|d: var/tmp/mysqld|g; print $_; } diff --git a/scripts/sys_schema/CMakeLists.txt b/scripts/sys_schema/CMakeLists.txt index ccb268cc4fd..dc023174fc7 100644 --- a/scripts/sys_schema/CMakeLists.txt +++ b/scripts/sys_schema/CMakeLists.txt @@ -130,6 +130,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/views/p_s/session_ssl_status.sql ${CMAKE_CURRENT_SOURCE_DIR}/procedures/create_synonym_db.sql ${CMAKE_CURRENT_SOURCE_DIR}/procedures/execute_prepared_stmt.sql ${CMAKE_CURRENT_SOURCE_DIR}/procedures/diagnostics.sql +${CMAKE_CURRENT_SOURCE_DIR}/procedures/optimizer_switch.sql ${CMAKE_CURRENT_SOURCE_DIR}/procedures/ps_statement_avg_latency_histogram.sql ${CMAKE_CURRENT_SOURCE_DIR}/procedures/ps_trace_statement_digest.sql ${CMAKE_CURRENT_SOURCE_DIR}/procedures/ps_trace_thread.sql diff --git a/scripts/sys_schema/procedures/optimizer_switch.sql b/scripts/sys_schema/procedures/optimizer_switch.sql new file mode 100644 index 00000000000..febeabc1208 --- /dev/null +++ b/scripts/sys_schema/procedures/optimizer_switch.sql @@ -0,0 +1,69 @@ +-- Copyright (C) 2023, MariaDB +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; version 2 of the License. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +DROP PROCEDURE IF EXISTS optimizer_switch_choice; +DROP PROCEDURE IF EXISTS optimizer_switch_on; +DROP PROCEDURE IF EXISTS optimizer_switch_off; +DELIMITER $$ + +CREATE DEFINER='mariadb.sys'@'localhost' PROCEDURE optimizer_switch_choice(IN on_off VARCHAR(3)) +COMMENT 'return @@optimizer_switch options as a result set for easier readability' +SQL SECURITY INVOKER +NOT DETERMINISTIC +CONTAINS SQL +BEGIN + DECLARE tmp VARCHAR(1024); + DECLARE opt VARCHAR(1024); + DECLARE start INT; + DECLARE end INT; + DECLARE pos INT; + set tmp=concat(@@optimizer_switch,","); + CREATE OR REPLACE TEMPORARY TABLE tmp_opt_switch (a varchar(64), opt CHAR(3)) character set latin1 engine=heap; + set start=1; + FIND_OPTIONS: + LOOP + set pos= INSTR(SUBSTR(tmp, start), ","); + if (pos = 0) THEN + LEAVE FIND_OPTIONS; + END IF; + set opt= MID(tmp, start, pos-1); + set end= INSTR(opt, "="); + insert into tmp_opt_switch values(LEFT(opt,end-1),SUBSTR(opt,end+1)); + set start=start + pos; + END LOOP; + SELECT t.a as "option",t.opt from tmp_opt_switch as t where t.opt = on_off order by a; + DROP TEMPORARY TABLE tmp_opt_switch; +END$$ + +CREATE DEFINER='mariadb.sys'@'localhost' PROCEDURE optimizer_switch_on() +COMMENT 'return @@optimizer_switch options that are on' +SQL SECURITY INVOKER +NOT DETERMINISTIC +CONTAINS SQL +BEGIN + call optimizer_switch_choice("on"); +END$$ + +CREATE DEFINER='mariadb.sys'@'localhost' PROCEDURE optimizer_switch_off() +COMMENT 'return @@optimizer_switch options that are off' +SQL SECURITY INVOKER +NOT DETERMINISTIC +CONTAINS SQL +BEGIN + call optimizer_switch_choice("off"); +END$$ + +DELIMITER ; + diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 0e4c2424942..f4101832214 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -175,6 +175,7 @@ SET (SQL_SOURCE sql_tvc.cc sql_tvc.h opt_split.cc rowid_filter.cc rowid_filter.h + optimizer_costs.h optimizer_defaults.h opt_trace.cc table_cache.cc encryption.cc temporary_tables.cc json_table.cc diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc index 67c8a8bca4f..a7920ade939 100644 --- a/sql/ddl_log.cc +++ b/sql/ddl_log.cc @@ -2741,6 +2741,8 @@ int ddl_log_execute_recovery() thd->thread_stack= (char*) &thd; thd->store_globals(); thd->init(); // Needed for error messages + thd->set_query_inner((char*) STRING_WITH_LEN("intern:ddl_log_execute_recovery"), + default_charset_info); thd->log_all_errors= (global_system_variables.log_warnings >= 3); recovery_state.drop_table.free(); diff --git a/sql/events.cc b/sql/events.cc index 6ecdf975178..01a11461655 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -906,6 +906,8 @@ Events::init(THD *thd, bool opt_noacl_or_bootstrap) */ thd->thread_stack= (char*) &thd; thd->store_globals(); + thd->set_query_inner((char*) STRING_WITH_LEN("intern:Events::init"), + default_charset_info); /* Set current time for the thread that handles events. Current time is stored in data member start_time of THD class. diff --git a/sql/filesort.cc b/sql/filesort.cc index bf5520955c9..96eabfdab89 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -63,10 +63,6 @@ static Addon_fields *get_addon_fields(TABLE *table, uint sortlength, uint *addon_length, uint *m_packable_length); -static bool check_if_pq_applicable(Sort_param *param, SORT_INFO *info, - TABLE *table, - ha_rows records, size_t memory_available); - static void store_key_part_length(uint32 num, uchar *to, uint bytes) { switch(bytes) { @@ -91,42 +87,62 @@ static uint32 read_keypart_length(const uchar *from, uint bytes) } -// @param sortlen [Maximum] length of the sort key -void Sort_param::init_for_filesort(uint sortlen, TABLE *table, - ha_rows maxrows, Filesort *filesort) +/* + Initialize Sort_param for doing a filesort + + @param table Table to sort + @param Filesort Filesort parameter to filesort() + @param sortlen [Maximum] length of the sort key + @param limit_rows Number of rows to return (may be less than rows to sort) +*/ + +void Sort_param::init_for_filesort(TABLE *table, Filesort *filesort, + uint sortlen, ha_rows limit_rows_arg) { DBUG_ASSERT(addon_fields == NULL); - sort_length= sortlen; - ref_length= table->file->ref_length; - accepted_rows= filesort->accepted_rows; - if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && !table->fulltext_searched && !filesort->sort_positions) { - /* - Get the descriptors of all fields whose values are appended + /* + Get the descriptors of all fields whose values are appended to sorted fields and get its total length in addon_buf.length */ - addon_fields= get_addon_fields(table, sort_length, &addon_length, + addon_fields= get_addon_fields(table, sortlen, &addon_length, &m_packable_length); } - if (using_addon_fields()) + DBUG_ASSERT((using_addon_fields() == 0 || addon_length != 0)); + + setup_lengths_and_limit(table, sortlen, addon_length, limit_rows_arg); + accepted_rows= filesort->accepted_rows; +} + + +void Sort_param::setup_lengths_and_limit(TABLE *table, + uint sort_len_arg, + uint addon_length_arg, + ha_rows limit_rows_arg) +{ + sort_form= table; + sort_length= sort_len_arg; + limit_rows= limit_rows_arg; + ref_length= table->file->ref_length; + + if (addon_length_arg) { - DBUG_ASSERT(addon_length < UINT_MAX32); - res_length= addon_length; + DBUG_ASSERT(addon_length_arg < UINT_MAX32); + res_length= addon_length_arg; } else { res_length= ref_length; /* - The reference to the record is considered - as an additional sorted field + The reference (rowid) to the record is considered as an additional + sorted field as we want to access rows in rowid order if possible. */ sort_length+= ref_length; } - rec_length= sort_length + addon_length; - max_rows= maxrows; + rec_length= sort_length + addon_length_arg; } @@ -161,6 +177,7 @@ void Sort_param::try_to_pack_addons(ulong max_length_for_sort_data) rec_length+= sz; } + /** Sort a table. Creates a set of pointers that can be used to read the rows @@ -204,7 +221,8 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, bool allow_packing_for_sortkeys; Bounded_queue pq; SQL_SELECT *const select= filesort->select; - ha_rows max_rows= filesort->limit; + Sort_costs costs; + ha_rows limit_rows= filesort->limit; uint s_length= 0, sort_len; Sort_keys *sort_keys; DBUG_ENTER("filesort"); @@ -249,7 +267,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, param.sort_keys= sort_keys; sort_len= sortlength(thd, sort_keys, &allow_packing_for_sortkeys); - param.init_for_filesort(sort_len, table, max_rows, filesort); + param.init_for_filesort(table, filesort, sort_len, limit_rows); if (!param.accepted_rows) param.accepted_rows= ¬_used; @@ -264,21 +282,54 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, else thd->inc_status_sort_scan(); thd->query_plan_flags|= QPLAN_FILESORT; - tracker->report_use(thd, max_rows); + tracker->report_use(thd, limit_rows); // If number of rows is not known, use as much of sort buffer as possible. num_rows= table->file->estimate_rows_upper_bound(); - if (check_if_pq_applicable(¶m, sort, - table, num_rows, memory_available)) + costs.compute_sort_costs(¶m, num_rows, memory_available, + param.using_addon_fields()); + + if (costs.fastest_sort == NO_SORT_POSSIBLE_OUT_OF_MEM) { - DBUG_PRINT("info", ("filesort PQ is applicable")); + my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR_LOG + ME_FATAL)); + goto err; + } + + if (costs.fastest_sort == PQ_SORT_ALL_FIELDS || + costs.fastest_sort == PQ_SORT_ORDER_BY_FIELDS) + { + /* We are going to use priorty queue */ thd->query_plan_flags|= QPLAN_FILESORT_PRIORITY_QUEUE; status_var_increment(thd->status_var.filesort_pq_sorts_); tracker->incr_pq_used(); param.using_pq= true; const size_t compare_length= param.sort_length; DBUG_ASSERT(param.using_packed_sortkeys() == false); + + if (costs.fastest_sort == PQ_SORT_ORDER_BY_FIELDS && sort->addon_fields) + { + /* + Upper code have addon_fields enabled, which we have decided to + not use. Let's delete them. + */ + my_free(sort->addon_fields); + sort->addon_fields= NULL; + param.addon_fields= NULL; + param.res_length= param.ref_length; + /* + Add the ref (rowid which is stored last in the sort key) to the sort, + as we want to retrive rows in id order, if possible. + */ + param.sort_length+= param.ref_length; + param.rec_length= param.sort_length; + } + + /* Priority queues needs one extra element for doing INSERT */ + param.max_keys_per_buffer= (uint) param.limit_rows + 1; + if (!sort->alloc_sort_buffer(param.max_keys_per_buffer, param.rec_length)) + goto err; + /* For PQ queries (with limit) we know exactly how many pointers/records we have in the buffer, so to simplify things, we initialize @@ -286,7 +337,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, point in doing lazy initialization). */ sort->init_record_pointers(); - if (pq.init(param.max_rows, + if (pq.init(param.limit_rows, true, // max_at_top NULL, // compare_function compare_length, @@ -312,9 +363,10 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, tracker->report_sort_keys_format(param.using_packed_sortkeys()); param.using_pq= false; + /* Allocate sort buffer. Use as much memory as possible. */ size_t min_sort_memory= MY_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2); - set_if_bigger(min_sort_memory, sizeof(Merge_chunk*)*MERGEBUFF2); + set_if_bigger(min_sort_memory, sizeof(Merge_chunk*) * MERGEBUFF2); while (memory_available >= min_sort_memory) { ulonglong keys= memory_available / (param.rec_length + sizeof(char*)); @@ -346,18 +398,17 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, if (param.tmp_buffer.alloc(param.sort_length)) goto err; - if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX, - DISK_BUFFER_SIZE, MYF(MY_WME))) + if (open_cached_file(&buffpek_pointers, mysql_tmpdir, TEMP_PREFIX, + DISK_CHUNK_SIZE, MYF(MY_WME))) goto err; - param.sort_form= table; param.local_sortorder= Bounds_checked_array(filesort->sortorder, s_length); num_rows= find_all_keys(thd, ¶m, select, sort, &buffpek_pointers, - &tempfile, + &tempfile, pq.is_initialized() ? &pq : NULL, &sort->found_rows); if (num_rows == HA_POS_ERROR) @@ -397,10 +448,10 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, sort->buffpek.length= maxbuffer; buffpek= (Merge_chunk *) sort->buffpek.str; close_cached_file(&buffpek_pointers); - /* Open cached file if it isn't open */ - if (! my_b_inited(outfile) && - open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, - MYF(MY_WME))) + /* Open cached file if it isn't open */ + if (!my_b_inited(outfile) && + open_cached_file(outfile, mysql_tmpdir, TEMP_PREFIX, DISK_CHUNK_SIZE, + MYF(MY_WME))) goto err; if (reinit_io_cache(outfile,WRITE_CACHE,0L,0,0)) goto err; @@ -416,11 +467,11 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, maxbuffer--; // Offset from 0 if (merge_many_buff(¶m, sort->get_raw_buf(), - buffpek,&maxbuffer, - &tempfile)) + buffpek, &maxbuffer, + &tempfile)) goto err; if (flush_io_cache(&tempfile) || - reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) + reinit_io_cache(&tempfile, READ_CACHE, 0L,0,0)) goto err; if (merge_index(¶m, sort->get_raw_buf(), @@ -431,10 +482,10 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, goto err; } - if (num_rows > param.max_rows) + if (num_rows > param.limit_rows) { // If find_all_keys() produced more results than the query LIMIT. - num_rows= param.max_rows; + num_rows= param.limit_rows; } error= 0; @@ -809,7 +860,7 @@ static void dbug_print_record(TABLE *table, bool print_rowid) { if (no free space in sort_keys buffers) { - sort sort_keys buffer; + qsort sort_keys buffer; dump sorted sequence to 'tempfile'; dump BUFFPEK describing sequence location into 'buffpek_pointers'; } @@ -836,7 +887,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, ha_rows *found_rows) { int error, quick_select; - uint idx, indexpos; + uint num_elements_in_buffer, indexpos; uchar *ref_pos, *next_pos, ref_buff[MAX_REFLENGTH]; TABLE *sort_form; handler *file; @@ -851,15 +902,14 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, (select ? select->quick ? "ranges" : "where": "every row"))); - idx=indexpos=0; - error=quick_select=0; - sort_form=param->sort_form; - file=sort_form->file; - ref_pos= ref_buff; - quick_select=select && select->quick; + num_elements_in_buffer= indexpos= 0; + error= 0; *found_rows= 0; - ref_pos= &file->ref[0]; - next_pos=ref_pos; + sort_form= param->sort_form; + file= sort_form->file; + ref_pos= ref_buff; + quick_select= select && select->quick; + next_pos= ref_pos= &file->ref[0]; DBUG_EXECUTE_IF("show_explain_in_find_all_keys", dbug_serve_apcs(thd, 1); @@ -867,7 +917,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, if (!quick_select) { - next_pos=(uchar*) 0; /* Find records in sequence */ + next_pos= (uchar*) 0; /* Find records in sequence */ DBUG_EXECUTE_IF("bug14365043_1", DBUG_SET("+d,ha_rnd_init_fail");); if (unlikely(file->ha_rnd_init_with_error(1))) @@ -966,12 +1016,13 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, { if (fs_info->isfull()) { - if (write_keys(param, fs_info, idx, buffpek_pointers, tempfile)) + if (write_keys(param, fs_info, num_elements_in_buffer, + buffpek_pointers, tempfile)) goto err; - idx= 0; + num_elements_in_buffer= 0; indexpos++; } - if (idx == 0) + if (num_elements_in_buffer == 0) fs_info->init_next_record_pointer(); uchar *start_of_rec= fs_info->get_next_record_pointer(); @@ -979,7 +1030,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, ref_pos, using_packed_sortkeys); if (packed_format && rec_sz != param->rec_length) fs_info->adjust_next_record_pointer(rec_sz); - idx++; + num_elements_in_buffer++; } num_records++; (*param->accepted_rows)++; @@ -1015,8 +1066,9 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, file->print_error(error,MYF(ME_ERROR_LOG)); DBUG_RETURN(HA_POS_ERROR); } - if (indexpos && idx && - write_keys(param, fs_info, idx, buffpek_pointers, tempfile)) + if (indexpos && num_elements_in_buffer && + write_keys(param, fs_info, num_elements_in_buffer, buffpek_pointers, + tempfile)) DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ (*found_rows)= num_records; @@ -1065,7 +1117,7 @@ write_keys(Sort_param *param, SORT_INFO *fs_info, uint count, fs_info->sort_buffer(param, count); if (!my_b_inited(tempfile) && - open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE, + open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_CHUNK_SIZE, MYF(MY_WME))) DBUG_RETURN(1); /* purecov: inspected */ /* check we won't have more buffpeks than we can possibly keep in memory */ @@ -1073,15 +1125,13 @@ write_keys(Sort_param *param, SORT_INFO *fs_info, uint count, DBUG_RETURN(1); buffpek.set_file_position(my_b_tell(tempfile)); - if ((ha_rows) count > param->max_rows) - count=(uint) param->max_rows; /* purecov: inspected */ + if ((ha_rows) count > param->limit_rows) + count=(uint) param->limit_rows; /* purecov: inspected */ buffpek.set_rowcount(static_cast(count)); for (uint ix= 0; ix < count; ++ix) { uchar *record= fs_info->get_sorted_record(ix); - - if (my_b_write(tempfile, record, param->get_record_length(record))) DBUG_RETURN(1); /* purecov: inspected */ } @@ -1496,144 +1546,6 @@ static bool save_index(Sort_param *param, uint count, } -/** - Test whether priority queue is worth using to get top elements of an - ordered result set. If it is, then allocates buffer for required amount of - records - - @param param Sort parameters. - @param filesort_info Filesort information. - @param table Table to sort. - @param num_rows Estimate of number of rows in source record set. - @param memory_available Memory available for sorting. - - DESCRIPTION - Given a query like this: - SELECT ... FROM t ORDER BY a1,...,an LIMIT max_rows; - This function tests whether a priority queue should be used to keep - the result. Necessary conditions are: - - estimate that it is actually cheaper than merge-sort - - enough memory to store the records. - - If we don't have space for records, but we *do* have - space for keys, we may rewrite 'table' to sort with - references to records instead of additional data. - (again, based on estimates that it will actually be cheaper). - - @retval - true - if it's ok to use PQ - false - PQ will be slower than merge-sort, or there is not enough memory. -*/ - -static bool check_if_pq_applicable(Sort_param *param, - SORT_INFO *filesort_info, - TABLE *table, ha_rows num_rows, - size_t memory_available) -{ - DBUG_ENTER("check_if_pq_applicable"); - - /* - How much Priority Queue sort is slower than qsort. - Measurements (see unit test) indicate that PQ is roughly 3 times slower. - */ - const double PQ_slowness= 3.0; - - if (param->max_rows == HA_POS_ERROR) - { - DBUG_PRINT("info", ("No LIMIT")); - DBUG_RETURN(false); - } - - if (param->max_rows + 2 >= UINT_MAX) - { - DBUG_PRINT("info", ("Too large LIMIT")); - DBUG_RETURN(false); - } - - size_t num_available_keys= - memory_available / (param->rec_length + sizeof(char*)); - // We need 1 extra record in the buffer, when using PQ. - param->max_keys_per_buffer= (uint) param->max_rows + 1; - - if (num_rows < num_available_keys) - { - // The whole source set fits into memory. - if (param->max_rows < num_rows/PQ_slowness ) - { - filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, - param->rec_length); - DBUG_RETURN(filesort_info->sort_buffer_size() != 0); - } - else - { - // PQ will be slower. - DBUG_RETURN(false); - } - } - - // Do we have space for LIMIT rows in memory? - if (param->max_keys_per_buffer < num_available_keys) - { - filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, - param->rec_length); - DBUG_RETURN(filesort_info->sort_buffer_size() != 0); - } - - // Try to strip off addon fields. - if (param->addon_fields) - { - const size_t row_length= - param->sort_length + param->ref_length + sizeof(char*); - num_available_keys= memory_available / row_length; - - // Can we fit all the keys in memory? - if (param->max_keys_per_buffer < num_available_keys) - { - const double sort_merge_cost= - get_merge_many_buffs_cost_fast(num_rows, - num_available_keys, - (uint)row_length); - /* - PQ has cost: - (insert + qsort) * log(queue size) / TIME_FOR_COMPARE_ROWID + - cost of file lookup afterwards. - The lookup cost is a bit pessimistic: we take scan_time and assume - that on average we find the row after scanning half of the file. - A better estimate would be lookup cost, but note that we are doing - random lookups here, rather than sequential scan. - */ - const double pq_cpu_cost= - (PQ_slowness * num_rows + param->max_keys_per_buffer) * - log((double) param->max_keys_per_buffer) / TIME_FOR_COMPARE_ROWID; - const double pq_io_cost= - param->max_rows * table->file->scan_time() / 2.0; - const double pq_cost= pq_cpu_cost + pq_io_cost; - - if (sort_merge_cost < pq_cost) - DBUG_RETURN(false); - - filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, - param->sort_length + param->ref_length); - - if (filesort_info->sort_buffer_size() > 0) - { - /* Make attached data to be references instead of fields. */ - my_free(filesort_info->addon_fields); - filesort_info->addon_fields= NULL; - param->addon_fields= NULL; - - param->res_length= param->ref_length; - param->sort_length+= param->ref_length; - param->rec_length= param->sort_length; - - DBUG_RETURN(true); - } - } - } - DBUG_RETURN(false); -} - - /** Merge buffers to make < MERGEBUFF2 buffers. */ int merge_many_buff(Sort_param *param, Sort_buffer sort_buffer, @@ -1645,28 +1557,28 @@ int merge_many_buff(Sort_param *param, Sort_buffer sort_buffer, DBUG_ENTER("merge_many_buff"); if (*maxbuffer < MERGEBUFF2) - DBUG_RETURN(0); /* purecov: inspected */ + DBUG_RETURN(0); /* purecov: inspected */ if (flush_io_cache(t_file) || - open_cached_file(&t_file2,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE, - MYF(MY_WME))) + open_cached_file(&t_file2, mysql_tmpdir, TEMP_PREFIX, DISK_CHUNK_SIZE, + MYF(MY_WME))) DBUG_RETURN(1); /* purecov: inspected */ - from_file= t_file ; to_file= &t_file2; + from_file= t_file; to_file= &t_file2; while (*maxbuffer >= MERGEBUFF2) { - if (reinit_io_cache(from_file,READ_CACHE,0L,0,0)) + if (reinit_io_cache(from_file, READ_CACHE, 0L, 0, 0)) goto cleanup; - if (reinit_io_cache(to_file,WRITE_CACHE,0L,0,0)) + if (reinit_io_cache(to_file, WRITE_CACHE,0L, 0, 0)) goto cleanup; lastbuff=buffpek; - for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF) + for (i= 0; i <= *maxbuffer - MERGEBUFF * 3 / 2 ; i+= MERGEBUFF) { - if (merge_buffers(param,from_file,to_file,sort_buffer, lastbuff++, - buffpek+i,buffpek+i+MERGEBUFF-1,0)) + if (merge_buffers(param, from_file, to_file, sort_buffer, lastbuff++, + buffpek + i, buffpek + i + MERGEBUFF - 1, 0)) goto cleanup; } - if (merge_buffers(param,from_file,to_file,sort_buffer, lastbuff++, - buffpek+i,buffpek+ *maxbuffer,0)) + if (merge_buffers(param, from_file, to_file, sort_buffer, lastbuff++, + buffpek + i, buffpek + *maxbuffer, 0)) break; /* purecov: inspected */ if (flush_io_cache(to_file)) break; /* purecov: inspected */ @@ -1764,7 +1676,7 @@ ulong read_to_buffer(IO_CACHE *fromfile, Merge_chunk *buffpek, num_bytes_read= bytes_to_read; buffpek->init_current_key(); - buffpek->advance_file_position(num_bytes_read); /* New filepos */ + buffpek->advance_file_position(num_bytes_read); /* New filepos */ buffpek->decrement_rowcount(count); buffpek->set_mem_count(count); return (ulong) num_bytes_read; @@ -1863,7 +1775,7 @@ bool merge_buffers(Sort_param *param, IO_CACHE *from_file, maxcount= (ulong) (param->max_keys_per_buffer/((uint) (Tb-Fb) +1)); to_start_filepos= my_b_tell(to_file); strpos= sort_buffer.array(); - org_max_rows=max_rows= param->max_rows; + org_max_rows= max_rows= param->limit_rows; set_if_bigger(maxcount, 1); @@ -1878,17 +1790,17 @@ bool merge_buffers(Sort_param *param, IO_CACHE *from_file, first_cmp_arg= param->get_compare_argument(&sort_length); } if (unlikely(init_queue(&queue, (uint) (Tb-Fb)+1, - offsetof(Merge_chunk,m_current_key), 0, + offsetof(Merge_chunk,m_current_key), 0, (queue_compare) cmp, first_cmp_arg, 0, 0))) DBUG_RETURN(1); /* purecov: inspected */ - const size_t chunk_sz = (sort_buffer.size()/((uint) (Tb-Fb) +1)); - for (buffpek= Fb ; buffpek <= Tb ; buffpek++) + const size_t chunk_sz= (sort_buffer.size()/((uint) (Tb-Fb) +1)); + for (buffpek= Fb; buffpek <= Tb; buffpek++) { buffpek->set_buffer(strpos, strpos + chunk_sz); buffpek->set_max_keys(maxcount); bytes_read= read_to_buffer(from_file, buffpek, param, packed_format); if (unlikely(bytes_read == (ulong) -1)) - goto err; /* purecov: inspected */ + goto err; /* purecov: inspected */ strpos+= chunk_sz; // If less data in buffers than expected buffpek->set_max_keys(buffpek->mem_count()); @@ -1970,11 +1882,11 @@ bool merge_buffers(Sort_param *param, IO_CACHE *from_file, */ if (!check_dupl_count || dupl_count >= min_dupl_count) { - if(my_b_write(to_file, - src + (offset_for_packing ? - rec_length - res_length : // sort length - wr_offset), - bytes_to_write)) + if (my_b_write(to_file, + src + (offset_for_packing ? + rec_length - res_length : // sort length + wr_offset), + bytes_to_write)) goto err; /* purecov: inspected */ } if (cmp) @@ -2084,7 +1996,7 @@ bool merge_buffers(Sort_param *param, IO_CACHE *from_file, bytes_read != 0); end: - lastbuff->set_rowcount(MY_MIN(org_max_rows-max_rows, param->max_rows)); + lastbuff->set_rowcount(MY_MIN(org_max_rows - max_rows, param->limit_rows)); lastbuff->set_file_position(to_start_filepos); cleanup: @@ -2171,8 +2083,8 @@ Type_handler_timestamp_common::sort_length(THD *thd, void Type_handler_int_result::sort_length(THD *thd, - const Type_std_attributes *item, - SORT_FIELD_ATTR *sortorder) const + const Type_std_attributes *item, + SORT_FIELD_ATTR *sortorder) const { sortorder->original_length= sortorder->length= 8; // Sizof intern longlong } @@ -2180,8 +2092,8 @@ Type_handler_int_result::sort_length(THD *thd, void Type_handler_real_result::sort_length(THD *thd, - const Type_std_attributes *item, - SORT_FIELD_ATTR *sortorder) const + const Type_std_attributes *item, + SORT_FIELD_ATTR *sortorder) const { sortorder->original_length= sortorder->length= sizeof(double); } @@ -2205,13 +2117,13 @@ Type_handler_decimal_result::sort_length(THD *thd, @param thd Thread handler @param sortorder Order of items to sort @param s_length Number of items to sort - @param allow_packing_for_sortkeys [out] set to false if packing sort keys is not - allowed + @param allow_packing_for_sortkeys [out] set to false if packing sort keys + is not allowed @note - * sortorder->length and other members are updated for each sort item. - * TODO what is the meaning of this value if some fields are using packing while - others are not? + - sortorder->length and other members are updated for each sort item. + - TODO what is the meaning of this value if some fields are using packing + while others are not? @return Total length of sort buffer in bytes diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc index 5a51300a0fa..e1cd7c566bb 100644 --- a/sql/filesort_utils.cc +++ b/sql/filesort_utils.cc @@ -19,23 +19,106 @@ #include "sql_const.h" #include "sql_sort.h" #include "table.h" - +#include "optimizer_defaults.h" PSI_memory_key key_memory_Filesort_buffer_sort_keys; -namespace { -/** - A local helper function. See comments for get_merge_buffers_cost(). - */ -double get_merge_cost(ha_rows num_elements, ha_rows num_buffers, uint elem_size) +const LEX_CSTRING filesort_names[]= { - return - 2.0 * ((double) num_elements * elem_size) / IO_SIZE - + (double) num_elements * log((double) num_buffers) / - (TIME_FOR_COMPARE_ROWID * M_LN2); + { STRING_WITH_LEN("priority_queue with addon fields")}, + { STRING_WITH_LEN("priority_queue with row lookup")}, + { STRING_WITH_LEN("merge_sort with addon fields")}, + { STRING_WITH_LEN("merge_sort with row lookup)")}, + { STRING_WITH_LEN("Error while computing filesort cost")} +}; + +/* + Different ways to do sorting: + Merge Sort -> Without addon Fields, with fixed length + Merge Sort -> Without addon Fields, with dynamic length + Merge Sort -> With addon Fields, with fixed length + Merge Sort -> With addon Fields, with dynamic length + + Priority queue -> Without addon fields + Priority queue -> With addon fields + + With PQ (Priority queue) we could have a simple key (memcmp) or a + complex key (double & varchar for example). This cost difference + is currently not considered. +*/ + + +/** + Compute the cost of running qsort over a set of rows. + @param num_rows How many rows will be sorted. + @param with_addon_fields Set to true if the sorted rows include the whole + row (with addon fields) or just the keys themselves. + + @retval + Cost of the operation. +*/ + +double get_qsort_sort_cost(ha_rows num_rows, bool with_addon_fields) +{ + const double row_copy_cost= with_addon_fields ? DEFAULT_ROW_COPY_COST : + DEFAULT_KEY_COPY_COST; + const double key_cmp_cost= DEFAULT_KEY_COMPARE_COST; + const double qsort_constant_factor= QSORT_SORT_SLOWNESS_CORRECTION_FACTOR * + (row_copy_cost + key_cmp_cost); + + return qsort_constant_factor * num_rows * log2(1.0 + num_rows); } + + +/** + Compute the cost of sorting num_rows and only retrieving queue_size rows. + @param num_rows How many rows will be sorted. + @param queue_size How many rows will be returned by the priority + queue. + @param with_addon_fields Set to true if the sorted rows include the whole + row (with addon fields) or just the keys themselves. + + @retval + Cost of the operation. +*/ + +double get_pq_sort_cost(size_t num_rows, size_t queue_size, + bool with_addon_fields) +{ + const double row_copy_cost= with_addon_fields ? DEFAULT_ROW_COPY_COST : + DEFAULT_KEY_COPY_COST; + const double key_cmp_cost= DEFAULT_KEY_COMPARE_COST; + /* 2 -> 1 insert, 1 pop from the queue*/ + const double pq_sort_constant_factor= PQ_SORT_SLOWNESS_CORRECTION_FACTOR * + 2.0 * (row_copy_cost + key_cmp_cost); + + return pq_sort_constant_factor * num_rows * log2(1.0 + queue_size); } + +/** + Compute the cost of merging "num_buffers" sorted buffers using a priority + queue. + + See comments for get_merge_buffers_cost(). +*/ + +static +double get_merge_cost(ha_rows num_elements, ha_rows num_buffers, + size_t elem_size, double compare_cost, + double disk_read_cost) +{ + /* 2 -> 1 read + 1 write */ + const double io_cost= (2.0 * (num_elements * elem_size + + DISK_CHUNK_SIZE - 1) / + DISK_CHUNK_SIZE) * disk_read_cost; + /* 2 -> 1 insert, 1 pop for the priority queue used to merge the buffers. */ + const double cpu_cost= (2.0 * num_elements * log2(1.0 + num_buffers) * + compare_cost) * PQ_SORT_SLOWNESS_CORRECTION_FACTOR; + return io_cost + cpu_cost; +} + + /** This is a simplified, and faster version of @see get_merge_many_buffs_cost(). We calculate the cost of merging buffers, by simulating the actions @@ -43,40 +126,52 @@ double get_merge_cost(ha_rows num_elements, ha_rows num_buffers, uint elem_size) see comments for get_merge_buffers_cost(). TODO: Use this function for Unique::get_use_cost(). */ + double get_merge_many_buffs_cost_fast(ha_rows num_rows, ha_rows num_keys_per_buffer, - uint elem_size) + size_t elem_size, + double key_compare_cost, + double disk_read_cost, + bool with_addon_fields) { + DBUG_ASSERT(num_keys_per_buffer != 0); + ha_rows num_buffers= num_rows / num_keys_per_buffer; ha_rows last_n_elems= num_rows % num_keys_per_buffer; double total_cost; + double full_buffer_sort_cost; - // Calculate CPU cost of sorting buffers. - total_cost= - ((num_buffers * num_keys_per_buffer * log(1.0 + num_keys_per_buffer) + - last_n_elems * log(1.0 + last_n_elems)) / - TIME_FOR_COMPARE_ROWID); - - // Simulate behavior of merge_many_buff(). + /* Calculate cost for sorting all merge buffers + the last one. */ + full_buffer_sort_cost= get_qsort_sort_cost(num_keys_per_buffer, + with_addon_fields); + total_cost= (num_buffers * full_buffer_sort_cost + + get_qsort_sort_cost(last_n_elems, with_addon_fields)); + + if (num_buffers >= MERGEBUFF2) + total_cost+= TMPFILE_CREATE_COST * 2; // We are creating 2 files. + + /* Simulate behavior of merge_many_buff(). */ while (num_buffers >= MERGEBUFF2) { - // Calculate # of calls to merge_buffers(). - const ha_rows loop_limit= num_buffers - MERGEBUFF*3/2; - const ha_rows num_merge_calls= 1 + loop_limit/MERGEBUFF; + /* Calculate # of calls to merge_buffers(). */ + const ha_rows loop_limit= num_buffers - MERGEBUFF * 3 / 2; + const ha_rows num_merge_calls= 1 + loop_limit / MERGEBUFF; const ha_rows num_remaining_buffs= num_buffers - num_merge_calls * MERGEBUFF; - // Cost of merge sort 'num_merge_calls'. + /* Cost of merge sort 'num_merge_calls'. */ total_cost+= num_merge_calls * - get_merge_cost(num_keys_per_buffer * MERGEBUFF, MERGEBUFF, elem_size); + get_merge_cost(num_keys_per_buffer * MERGEBUFF, MERGEBUFF, elem_size, + key_compare_cost, disk_read_cost); // # of records in remaining buffers. last_n_elems+= num_remaining_buffs * num_keys_per_buffer; // Cost of merge sort of remaining buffers. total_cost+= - get_merge_cost(last_n_elems, 1 + num_remaining_buffs, elem_size); + get_merge_cost(last_n_elems, 1 + num_remaining_buffs, elem_size, + key_compare_cost, disk_read_cost); num_buffers= num_merge_calls; num_keys_per_buffer*= MERGEBUFF; @@ -84,10 +179,139 @@ double get_merge_many_buffs_cost_fast(ha_rows num_rows, // Simulate final merge_buff call. last_n_elems+= num_keys_per_buffer * num_buffers; - total_cost+= get_merge_cost(last_n_elems, 1 + num_buffers, elem_size); + total_cost+= get_merge_cost(last_n_elems, 1 + num_buffers, elem_size, + key_compare_cost, disk_read_cost); return total_cost; } + +void Sort_costs::compute_fastest_sort() +{ + lowest_cost= DBL_MAX; + uint min_idx= NO_SORT_POSSIBLE_OUT_OF_MEM; + for (uint i= 0; i < FINAL_SORT_TYPE; i++) + { + if (lowest_cost > costs[i]) + { + min_idx= i; + lowest_cost= costs[i]; + } + } + fastest_sort= static_cast(min_idx); +} + + +/* + Calculate cost of using priority queue for filesort. + There are two options: using addon fields or not +*/ + +void Sort_costs::compute_pq_sort_costs(Sort_param *param, ha_rows num_rows, + size_t memory_available, + bool with_addon_fields) +{ + /* + Implementation detail of PQ. To be able to keep a PQ of size N we need + N+1 elements allocated so we can use the last element as "swap" space + for the "insert" operation. + TODO(cvicentiu): This should be left as an implementation detail inside + the PQ, not have the optimizer take it into account. + */ + size_t queue_size= param->limit_rows + 1; + size_t row_length, num_available_keys; + + costs[PQ_SORT_ALL_FIELDS]= DBL_MAX; + costs[PQ_SORT_ORDER_BY_FIELDS]= DBL_MAX; + + /* + We can't use priority queue if there's no limit or the limit is + too big. + */ + if (param->limit_rows == HA_POS_ERROR || + param->limit_rows >= UINT_MAX - 2) + return; + + /* Calculate cost without addon keys (probably using less memory) */ + row_length= param->sort_length + param->ref_length + sizeof(char*); + num_available_keys= memory_available / row_length; + + if (queue_size < num_available_keys) + { + handler *file= param->sort_form->file; + costs[PQ_SORT_ORDER_BY_FIELDS]= + get_pq_sort_cost(num_rows, queue_size, false) + + file->cost(file->ha_rnd_pos_call_time(MY_MIN(queue_size - 1, num_rows))); + } + + /* Calculate cost with addon fields */ + if (with_addon_fields) + { + row_length= param->rec_length + sizeof(char *); + num_available_keys= memory_available / row_length; + + if (queue_size < num_available_keys) + costs[PQ_SORT_ALL_FIELDS]= get_pq_sort_cost(num_rows, queue_size, true); + } +} + +/* + Calculate cost of using qsort optional merge sort for resolving filesort. + There are two options: using addon fields or not +*/ + +void Sort_costs::compute_merge_sort_costs(Sort_param *param, + ha_rows num_rows, + size_t memory_available, + bool with_addon_fields) +{ + size_t row_length= param->sort_length + param->ref_length + sizeof(char *); + size_t num_available_keys= memory_available / row_length; + + costs[MERGE_SORT_ALL_FIELDS]= DBL_MAX; + costs[MERGE_SORT_ORDER_BY_FIELDS]= DBL_MAX; + + if (num_available_keys) + { + handler *file= param->sort_form->file; + costs[MERGE_SORT_ORDER_BY_FIELDS]= + get_merge_many_buffs_cost_fast(num_rows, num_available_keys, + row_length, DEFAULT_KEY_COMPARE_COST, + default_optimizer_costs.disk_read_cost, + false) + + file->cost(file->ha_rnd_pos_call_time(MY_MIN(param->limit_rows, num_rows))); + } + if (with_addon_fields) + { + /* Compute cost of merge sort *if* we strip addon fields. */ + row_length= param->rec_length + sizeof(char *); + num_available_keys= memory_available / row_length; + + if (num_available_keys) + costs[MERGE_SORT_ALL_FIELDS]= + get_merge_many_buffs_cost_fast(num_rows, num_available_keys, + row_length, DEFAULT_KEY_COMPARE_COST, + DISK_READ_COST_THD(thd), + true); + } + + /* + TODO(cvicentiu) we do not handle dynamic length fields yet. + The code should decide here if the format is FIXED length or DYNAMIC + and fill in the appropriate costs. + */ +} + +void Sort_costs::compute_sort_costs(Sort_param *param, ha_rows num_rows, + size_t memory_available, + bool with_addon_fields) +{ + compute_pq_sort_costs(param, num_rows, memory_available, + with_addon_fields); + compute_merge_sort_costs(param, num_rows, memory_available, + with_addon_fields); + compute_fastest_sort(); +} + /* alloc_sort_buffer() @@ -173,7 +397,7 @@ void Filesort_buffer::sort_buffer(const Sort_param *param, uint count) uchar **buffer= NULL; if (!param->using_packed_sortkeys() && - radixsort_is_appliccable(count, param->sort_length) && + radixsort_is_applicable(count, param->sort_length) && (buffer= (uchar**) my_malloc(PSI_INSTRUMENT_ME, count*sizeof(char*), MYF(MY_THREAD_SPECIFIC)))) { @@ -186,3 +410,66 @@ void Filesort_buffer::sort_buffer(const Sort_param *param, uint count) param->get_compare_function(), param->get_compare_argument(&size)); } + + +static +size_t get_sort_length(THD *thd, Item_field *item) +{ + SORT_FIELD_ATTR sort_attr; + sort_attr.type= ((item->field)->is_packable() ? + SORT_FIELD_ATTR::VARIABLE_SIZE : + SORT_FIELD_ATTR::FIXED_SIZE); + item->type_handler()->sort_length(thd, item, &sort_attr); + + return sort_attr.length + (item->maybe_null() ? 1 : 0); +} + + +/** + Calculate the cost of doing a filesort + + @param table Table to sort + @param Order_by Fields to sort + @param rows_to_read Number of rows to be sorted + @param limit_rows Number of rows in result (when using limit) + @param used_sort_type Set to the sort algorithm used + + @result cost of sorting +*/ + + +double cost_of_filesort(TABLE *table, ORDER *order_by, ha_rows rows_to_read, + ha_rows limit_rows, enum sort_type *used_sort_type) +{ + THD *thd= table->in_use; + Sort_costs costs; + Sort_param param; + size_t memory_available= (size_t) thd->variables.sortbuff_size; + uint sort_len= 0; + uint addon_field_length, num_addon_fields, num_nullable_fields; + uint packable_length; + bool with_addon_fields; + + for (ORDER *ptr= order_by; ptr ; ptr= ptr->next) + { + Item_field *field= (Item_field*) (*ptr->item)->real_item(); + size_t length= get_sort_length(thd, field); + set_if_smaller(length, thd->variables.max_sort_length); + sort_len+= (uint) length; + } + + with_addon_fields= + filesort_use_addons(table, sort_len, &addon_field_length, + &num_addon_fields, &num_nullable_fields, + &packable_length); + + /* Fill in the Sort_param structure so we can compute the sort costs */ + param.setup_lengths_and_limit(table, sort_len, addon_field_length, + limit_rows); + + costs.compute_sort_costs(¶m, rows_to_read, memory_available, + with_addon_fields); + + *used_sort_type= costs.fastest_sort; + return costs.lowest_cost; +} diff --git a/sql/filesort_utils.h b/sql/filesort_utils.h index 1962f149893..73aa2f76a18 100644 --- a/sql/filesort_utils.h +++ b/sql/filesort_utils.h @@ -16,16 +16,20 @@ #ifndef FILESORT_UTILS_INCLUDED #define FILESORT_UTILS_INCLUDED +#include "my_global.h" #include "my_base.h" #include "sql_array.h" +#include "handler.h" class Sort_param; -/* + +/** Calculate cost of merge sort @param num_rows Total number of rows. @param num_keys_per_buffer Number of keys per buffer. @param elem_size Size of each element. + @param key_compare_cost Cost to compare two keys during QSort & merge Calculates cost of merge sort by simulating call to merge_many_buff(). @@ -38,19 +42,82 @@ class Sort_param; See also comments get_merge_many_buffs_cost(). */ - double get_merge_many_buffs_cost_fast(ha_rows num_rows, ha_rows num_keys_per_buffer, - uint elem_size); + size_t elem_size, + double compare_cost, + bool with_addon_fields); + +/** + These are the current sorting algorithms we compute cost for: + + PQ_SORT_ALL_FIELDS Sort via priority queue, with addon fields. + PQ_SORT_ORDER_BY_FIELDS Sort via priority queue, without addon fields. + + MERGE_SORT_ALL_FIELDS Sort via merge sort, with addon fields. + MERGE_SORT_ORDER_BY_FIELDS Sort via merge sort, without addon fields. + + Note: + There is the possibility to do merge-sorting with dynamic length fields. + This is more expensive than if there are only fixed length fields, + however we do not (yet) account for that extra cost. We can extend the + cost computation in the future to cover that case as well. + + Effectively there are 4 possible combinations for merge sort: + With/without addon fields + With/without dynamic length fields. +*/ + +enum sort_type +{ + PQ_SORT_ALL_FIELDS= 0, + PQ_SORT_ORDER_BY_FIELDS, + MERGE_SORT_ALL_FIELDS, + MERGE_SORT_ORDER_BY_FIELDS, + + NO_SORT_POSSIBLE_OUT_OF_MEM, /* In case of errors */ + FINAL_SORT_TYPE= NO_SORT_POSSIBLE_OUT_OF_MEM +}; + +struct Sort_costs +{ + Sort_costs() : + fastest_sort(NO_SORT_POSSIBLE_OUT_OF_MEM), lowest_cost(DBL_MAX) {} + + void compute_sort_costs(Sort_param *param, ha_rows num_rows, + size_t memory_available, + bool with_addon_fields); + + /* Cache value for fastest_sort. */ + enum sort_type fastest_sort; + /* Cache value for lowest cost. */ + double lowest_cost; +private: + /* + Array to hold all computed costs. + TODO(cvicentiu) This array is only useful for debugging. If it's not + used in debugging code, it can be removed to reduce memory usage. + */ + double costs[FINAL_SORT_TYPE]; + + void compute_pq_sort_costs(Sort_param *param, ha_rows num_rows, + size_t memory_available, + bool with_addon_fields); + void compute_merge_sort_costs(Sort_param *param, ha_rows num_rows, + size_t memory_available, + bool with_addon_fields); + void compute_fastest_sort(); +}; + /** A wrapper class around the buffer used by filesort(). The sort buffer is a contiguous chunk of memory, containing both records to be sorted, and pointers to said records: - - |rec 0|record 1 |rec 2| ............ |ptr to rec2|ptr to rec1|ptr to rec0| + + | rec0 | rec1 | rec2 | ............ |ptr to rec2|ptr to rec1|ptr to rec0| Records will be inserted "left-to-right". Records are not necessarily fixed-size, they can be packed and stored without any "gaps". @@ -279,8 +346,14 @@ private: longlong m_idx; }; +/* Names for sort_type */ +extern const LEX_CSTRING filesort_names[]; + +double cost_of_filesort(TABLE *table, ORDER *order_by, ha_rows rows_to_read, + ha_rows limit_rows, enum sort_type *used_sort_type); + +double get_qsort_sort_cost(ha_rows num_rows, bool with_addon_fields); int compare_packed_sort_keys(void *sort_keys, unsigned char **a, unsigned char **b); qsort2_cmp get_packed_keys_compare_ptr(); - #endif // FILESORT_UTILS_INCLUDED diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 857545255f3..08e3b45e02b 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -6575,7 +6575,7 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *mrr_mode, + uint *mrr_mode, ha_rows limit, Cost_estimate *cost) { int error; @@ -6629,14 +6629,14 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, ha_rows tmp_rows; uint tmp_mrr_mode; m_mrr_buffer_size[i]= 0; - part_cost.reset(); + part_cost.reset(*file); tmp_mrr_mode= *mrr_mode; tmp_rows= (*file)-> multi_range_read_info_const(keyno, &m_part_seq_if, &m_partition_part_key_multi_range_hld[i], m_part_mrr_range_length[i], &m_mrr_buffer_size[i], - &tmp_mrr_mode, &part_cost); + &tmp_mrr_mode, limit, &part_cost); if (tmp_rows == HA_POS_ERROR) { m_part_spec= save_part_spec; @@ -6680,7 +6680,7 @@ ha_rows ha_partition::multi_range_read_info(uint keyno, uint n_ranges, { ha_rows tmp_rows; m_mrr_buffer_size[i]= 0; - part_cost.reset(); + part_cost.reset(*file); if ((tmp_rows= (*file)->multi_range_read_info(keyno, n_ranges, keys, key_parts, &m_mrr_buffer_size[i], @@ -9737,16 +9737,28 @@ uint ha_partition::get_biggest_used_partition(uint *part_index) time for scan */ -double ha_partition::scan_time() +IO_AND_CPU_COST ha_partition::scan_time() { - double scan_time= 0; + IO_AND_CPU_COST scan_time= {0,0}; uint i; DBUG_ENTER("ha_partition::scan_time"); for (i= bitmap_get_first_set(&m_part_info->read_partitions); i < m_tot_parts; i= bitmap_get_next_set(&m_part_info->read_partitions, i)) - scan_time+= m_file[i]->scan_time(); + { + IO_AND_CPU_COST cost= m_file[i]->scan_time(); + scan_time.io+= cost.io; + scan_time.cpu+= cost.cpu; + } + if (m_tot_parts) + { + /* + Add TABLE_SCAN_SETUP_COST for partitions to make cost similar to + in ha_scan_time() + */ + scan_time.cpu+= TABLE_SCAN_SETUP_COST * (m_tot_parts - 1); + } DBUG_RETURN(scan_time); } @@ -9760,34 +9772,78 @@ double ha_partition::scan_time() @return time for scanning index inx */ -double ha_partition::key_scan_time(uint inx) +IO_AND_CPU_COST ha_partition::key_scan_time(uint inx, ha_rows rows) { - double scan_time= 0; + IO_AND_CPU_COST scan_time= {0,0}; uint i; + uint partitions= bitmap_bits_set(&m_part_info->read_partitions); + ha_rows rows_per_part; DBUG_ENTER("ha_partition::key_scan_time"); + + if (partitions == 0) + DBUG_RETURN(scan_time); + set_if_bigger(rows, 1); + rows_per_part= (rows + partitions - 1)/partitions; + for (i= bitmap_get_first_set(&m_part_info->read_partitions); i < m_tot_parts; i= bitmap_get_next_set(&m_part_info->read_partitions, i)) - scan_time+= m_file[i]->key_scan_time(inx); + { + IO_AND_CPU_COST cost= m_file[i]->key_scan_time(inx, rows_per_part); + scan_time.io+= cost.io; + scan_time.cpu+= cost.cpu; + } DBUG_RETURN(scan_time); } -double ha_partition::keyread_time(uint inx, uint ranges, ha_rows rows) +IO_AND_CPU_COST ha_partition::keyread_time(uint inx, ulong ranges, ha_rows rows, + ulonglong blocks) { - double read_time= 0; + IO_AND_CPU_COST read_time= {0,0}; uint i; + uint partitions= bitmap_bits_set(&m_part_info->read_partitions); DBUG_ENTER("ha_partition::keyread_time"); - if (!ranges) - DBUG_RETURN(handler::keyread_time(inx, ranges, rows)); + if (partitions == 0) + DBUG_RETURN(read_time); + + ha_rows rows_per_part= (rows + partitions - 1)/partitions; for (i= bitmap_get_first_set(&m_part_info->read_partitions); i < m_tot_parts; i= bitmap_get_next_set(&m_part_info->read_partitions, i)) - read_time+= m_file[i]->keyread_time(inx, ranges, rows); + { + IO_AND_CPU_COST cost= m_file[i]->keyread_time(inx, ranges, rows_per_part, + blocks); + read_time.io+= cost.io; + read_time.cpu+= cost.cpu; + } + /* Add that we have to do a key lookup for all ranges in all partitions */ + read_time.cpu= (partitions-1) * ranges * KEY_LOOKUP_COST; DBUG_RETURN(read_time); } +IO_AND_CPU_COST ha_partition::rnd_pos_time(ha_rows rows) +{ + IO_AND_CPU_COST read_time= {0,0}; + uint i; + uint partitions= bitmap_bits_set(&m_part_info->read_partitions); + if (partitions == 0) + return read_time; + + ha_rows rows_per_part= (rows + partitions - 1)/partitions; + for (i= bitmap_get_first_set(&m_part_info->read_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + { + IO_AND_CPU_COST cost= m_file[i]->rnd_pos_time(rows_per_part); + read_time.io+= cost.io; + read_time.cpu+= cost.cpu; + } + return read_time; +} + + /** Find number of records in a range. @param inx Index number @@ -9844,6 +9900,8 @@ ha_rows ha_partition::records_in_range(uint inx, const key_range *min_key, if (estimated_rows && checked_rows && checked_rows >= min_rows_to_check) { + /* We cannot use page ranges when there is more than one partion */ + *pages= unused_page_range; DBUG_PRINT("info", ("records_in_range(inx %u): %lu (%lu * %lu / %lu)", inx, @@ -9857,6 +9915,8 @@ ha_rows ha_partition::records_in_range(uint inx, const key_range *min_key, DBUG_PRINT("info", ("records_in_range(inx %u): %lu", inx, (ulong) estimated_rows)); + /* We cannot use page ranges when there is more than one partion */ + *pages= unused_page_range; DBUG_RETURN(estimated_rows); } @@ -9887,33 +9947,6 @@ ha_rows ha_partition::estimate_rows_upper_bound() } -/* - Get time to read - - SYNOPSIS - read_time() - index Index number used - ranges Number of ranges - rows Number of rows - - RETURN VALUE - time for read - - DESCRIPTION - This will be optimised later to include whether or not the index can - be used with partitioning. To achieve we need to add another parameter - that specifies how many of the index fields that are bound in the ranges. - Possibly added as a new call to handlers. -*/ - -double ha_partition::read_time(uint index, uint ranges, ha_rows rows) -{ - DBUG_ENTER("ha_partition::read_time"); - - DBUG_RETURN(get_open_file_sample()->read_time(index, ranges, rows)); -} - - /** Number of rows in table. see handler.h @@ -12136,6 +12169,38 @@ ha_partition::can_convert_nocopy(const Field &field, return true; } +/* + Get table costs for the current statement that should be stored in + handler->cost variables. + + When we want to support many different table handlers, we should set + m_file[i]->costs to point to an unique cost structure per open + instance and call something similar as + TABLE_SHARE::update_optimizer_costs(handlerton *hton) and + handler::update_optimizer_costs(&costs) on it. +*/ + + +void ha_partition::set_optimizer_costs(THD *thd) +{ + handler::set_optimizer_costs(thd); + for (uint i= bitmap_get_first_set(&m_part_info->read_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + m_file[i]->set_optimizer_costs(thd); +} + +/* + Get unique table costs for the first instance of the handler and store + in table->share +*/ + +void ha_partition::update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + uint i= bitmap_get_first_set(&m_part_info->read_partitions); + m_file[i]->update_optimizer_costs(costs); +} + struct st_mysql_storage_engine partition_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 37529073391..86d8cdb7cee 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -919,7 +919,7 @@ public: ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *mrr_mode, + uint *mrr_mode, ha_rows limit, Cost_estimate *cost) override; ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, uint key_parts, uint *bufsz, @@ -1031,16 +1031,14 @@ public: /* Called in test_quick_select to determine if indexes should be used. */ - double scan_time() override; + IO_AND_CPU_COST scan_time() override; - double key_scan_time(uint inx) override; + IO_AND_CPU_COST key_scan_time(uint inx, ha_rows rows) override; - double keyread_time(uint inx, uint ranges, ha_rows rows) override; + IO_AND_CPU_COST keyread_time(uint inx, ulong ranges, ha_rows rows, + ulonglong blocks) override; + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) override; - /* - The next method will never be called if you do not implement indexes. - */ - double read_time(uint index, uint ranges, ha_rows rows) override; /* For the given range how many records are estimated to be in this range. Used by optimiser to calculate cost of using a particular index. @@ -1637,5 +1635,8 @@ public: bool can_convert_nocopy(const Field &field, const Column_definition &new_field) const override; + void set_optimizer_costs(THD *thd) override; + void update_optimizer_costs(OPTIMIZER_COSTS *costs) override; }; + #endif /* HA_PARTITION_INCLUDED */ diff --git a/sql/handler.cc b/sql/handler.cc index 837a7be7ad6..5884339c809 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -46,6 +46,7 @@ #include "ha_sequence.h" #include "rowid_filter.h" #include "mysys_err.h" +#include "optimizer_defaults.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" @@ -621,8 +622,44 @@ int ha_finalize_handlerton(st_plugin_int *plugin) } -const char *hton_no_exts[]= { 0 }; +/* + Get a pointer to the global engine optimizer costs (like + innodb.disk_read_cost) and store the pointer in the handlerton. + This is called once when a handlerton is created. + We also update the not set global costs with the default costs + to allow information_schema to print the real used values. +*/ + +static bool update_optimizer_costs(handlerton *hton) +{ + OPTIMIZER_COSTS costs= default_optimizer_costs; + LEX_CSTRING *name= hton_name(hton); + + if (hton->update_optimizer_costs) + hton->update_optimizer_costs(&costs); + + mysql_mutex_lock(&LOCK_optimizer_costs); + hton->optimizer_costs= get_or_create_optimizer_costs(name->str, + name->length); + if (!hton->optimizer_costs) + { + mysql_mutex_unlock(&LOCK_optimizer_costs); + return 1; // OOM + } + + /* Update not set values from current default costs */ + for (uint i=0 ; i < sizeof(OPTIMIZER_COSTS)/sizeof(double) ; i++) + { + double *var= ((double*) hton->optimizer_costs)+i; + if (*var == OPTIMIZER_COST_UNDEF) + *var= ((double*) &costs)[i]; + } + mysql_mutex_unlock(&LOCK_optimizer_costs); + return 0; +} + +const char *hton_no_exts[]= { 0 }; int ha_initialize_handlerton(st_plugin_int *plugin) { @@ -725,6 +762,10 @@ int ha_initialize_handlerton(st_plugin_int *plugin) hton->savepoint_offset= savepoint_alloc_size; savepoint_alloc_size+= tmp; hton2plugin[hton->slot]=plugin; + + if (!(hton->flags & HTON_HIDDEN) && update_optimizer_costs(hton)) + goto err_deinit; + if (hton->prepare) { total_ha_2pc++; @@ -764,7 +805,6 @@ int ha_initialize_handlerton(st_plugin_int *plugin) resolve_sysvar_table_options(hton); update_discovery_counters(hton, 1); - DBUG_RETURN(0); err_deinit: @@ -3209,6 +3249,7 @@ handler *handler::clone(const char *name, MEM_ROOT *mem_root) if (new_handler->ha_open(table, name, table->db_stat, HA_OPEN_IGNORE_IF_LOCKED, mem_root)) goto err; + new_handler->set_optimizer_costs(ha_thd()); return new_handler; @@ -3242,30 +3283,111 @@ LEX_CSTRING *handler::engine_name() /* - It is assumed that the value of the parameter 'ranges' can be only 0 or 1. - If ranges == 1 then the function returns the cost of index only scan - by index 'keyno' of one range containing 'rows' key entries. - If ranges == 0 then the function returns only the cost of copying - those key entries into the engine buffers. + Calclate the number of index blocks we are going to access when + doing 'ranges' index dives reading a total of 'rows' rows. */ -double handler::keyread_time(uint index, uint ranges, ha_rows rows) +ulonglong handler::index_blocks(uint index, uint ranges, ha_rows rows) { - DBUG_ASSERT(ranges == 0 || ranges == 1); - size_t len= table->key_info[index].key_length + ref_length; - if (table->file->is_clustering_key(index)) - len= table->s->stored_rec_length; - double cost= (double)rows*len/(stats.block_size+1)*IDX_BLOCK_COPY_COST; - if (ranges) + if (!stats.block_size) + return 0; // No disk storage + size_t len= table->key_storage_length(index); + ulonglong blocks= (rows * len / INDEX_BLOCK_FILL_FACTOR_DIV * + INDEX_BLOCK_FILL_FACTOR_MUL) / stats.block_size + ranges; + return blocks * stats.block_size / IO_SIZE; +} + + +/* + Calculate cost for an index scan for given index and number of records. + + @param index Index to use + @param ranges Number of ranges (b-tree dives in case of b-tree). + Used by partition engine + @param rows Number of expected rows + @param blocks Number of disk blocks to read (from range optimizer). + 0 if not known + + This function does not take in account into looking up the key, + copying the key to record and finding the next key. These cost are + handled in ha_keyread_time() +*/ + +IO_AND_CPU_COST handler::keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) +{ + IO_AND_CPU_COST cost; + ulonglong io_blocks= 0; + DBUG_ASSERT(ranges > 0); + + /* memory engine has stats.block_size == 0 */ + if (stats.block_size) { - uint keys_per_block= (uint) (stats.block_size*3/4/len+1); - ulonglong blocks= (rows+ keys_per_block- 1)/keys_per_block; - cost+= blocks; + if (!blocks) + { + /* Estimate length of index data */ + if (rows <= 1) // EQ_REF optimization + { + blocks= 1; + io_blocks= (stats.block_size + IO_SIZE - 1)/ IO_SIZE; + } + else + { + size_t len= table->key_storage_length(index); + blocks= ((ulonglong) ((rows * len / INDEX_BLOCK_FILL_FACTOR_DIV * + INDEX_BLOCK_FILL_FACTOR_MUL + + stats.block_size-1)) / stats.block_size + + (ranges - 1)); + io_blocks= blocks * stats.block_size / IO_SIZE; + } + } + else + io_blocks= blocks * stats.block_size / IO_SIZE; } + cost.io= (double) io_blocks; + cost.cpu= blocks * INDEX_BLOCK_COPY_COST; return cost; } +/* + Cost of doing a set of range scans and finding the key position. + This function is used both with index scans (in which case there should be + an additional KEY_COPY_COST) and when normal index + fetch row scan, + in which case there should an additional rnd_pos_time() cost. +*/ + +IO_AND_CPU_COST handler::ha_keyread_time(uint index, ulong ranges, + ha_rows rows, + ulonglong blocks) +{ + if (rows < ranges) + rows= ranges; + IO_AND_CPU_COST cost= keyread_time(index, ranges, rows, blocks); + cost.cpu+= ranges * KEY_LOOKUP_COST + (rows - ranges) * KEY_NEXT_FIND_COST; + return cost; +} + + +/* + Read rows from a clustered index + + Cost is similar to ha_rnd_pos_call_time() as a index_read() on a clustered + key has identical code as rnd_pos() (At least in InnoDB:) +*/ + +IO_AND_CPU_COST +handler::ha_keyread_clustered_time(uint index, ulong ranges, + ha_rows rows, + ulonglong blocks) +{ + if (rows < ranges) + rows= ranges; + IO_AND_CPU_COST cost= keyread_time(index, ranges, rows, blocks); + cost.cpu+= (ranges * ROW_LOOKUP_COST + (rows - ranges) * ROW_NEXT_FIND_COST); + return cost; +} + THD *handler::ha_thd(void) const { DBUG_ASSERT(!table || !table->in_use || table->in_use == current_thd); @@ -3338,7 +3460,7 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, name, ht->db_type, table_arg->db_stat, mode, test_if_locked)); - table= table_arg; + set_table(table_arg); DBUG_ASSERT(table->s == table_share); DBUG_ASSERT(m_lock_type == F_UNLCK); DBUG_PRINT("info", ("old m_lock_type: %d F_UNLCK %d", m_lock_type, F_UNLCK)); @@ -3374,7 +3496,7 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, m_psi= PSI_CALL_open_table(ha_table_share_psi(), this); } - if (table->s->db_options_in_use & HA_OPTION_READ_ONLY_DATA) + if (table_share->db_options_in_use & HA_OPTION_READ_ONLY_DATA) table->db_stat|=HA_READ_ONLY; (void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL @@ -3388,9 +3510,24 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, else dup_ref=ref+ALIGN_SIZE(ref_length); cached_table_flags= table_flags(); + /* Cache index flags */ + for (uint index= 0 ; index < table_share->keys ; index++) + table->key_info[index].index_flags= index_flags(index, 0, 1); + + if (!table_share->optimizer_costs_inited) + { + table_share->optimizer_costs_inited=1; + /* Copy data from global 'engine'.optimizer_costs to TABLE_SHARE */ + table_share->update_optimizer_costs(partition_ht()); + /* Update costs depend on table structure */ + update_optimizer_costs(&table_share->optimizer_costs); + } + + /* Copy current optimizer costs. Needed in case clone() is used */ + reset_statistics(); } - reset_statistics(); internal_tmp_table= MY_TEST(test_if_locked & HA_OPEN_INTERNAL_TABLE); + DBUG_RETURN(error); } @@ -3418,6 +3555,15 @@ int handler::ha_close(void) DBUG_RETURN(close()); } +void handler::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) +{ + DBUG_ASSERT(table_arg->s == share); + table= table_arg; + table_share= share; + costs= &share->optimizer_costs; + reset_statistics(); +} + int handler::ha_rnd_next(uchar *buf) { @@ -3450,6 +3596,9 @@ int handler::ha_rnd_next(uchar *buf) } table->status=result ? STATUS_NOT_FOUND: 0; + + DEBUG_SYNC(ha_thd(), "handler_rnd_next_end"); + DBUG_RETURN(result); } @@ -3672,7 +3821,7 @@ int handler::read_first_row(uchar * buf, uint primary_key) TODO remove the test for HA_READ_ORDER */ if (stats.deleted < 10 || primary_key >= MAX_KEY || - !(index_flags(primary_key, 0, 0) & HA_READ_ORDER)) + !(table->key_info[primary_key].index_flags & HA_READ_ORDER)) { if (likely(!(error= ha_rnd_init(1)))) { @@ -6434,7 +6583,7 @@ bool Discovered_table_list::add_file(const char *fname) { bool is_temp= strncmp(fname, STRING_WITH_LEN(tmp_file_prefix)) == 0; - if (is_temp && !with_temps) + if ((is_temp && !with_temps) || !strncmp(fname,STRING_WITH_LEN(ROCKSDB_DIRECTORY_NAME))) return 0; char tname[SAFE_NAME_LEN + 1]; @@ -6749,17 +6898,25 @@ extern "C" check_result_t handler_index_cond_check(void* h_arg) check_result_t res; DEBUG_SYNC(thd, "handler_index_cond_check"); - enum thd_kill_levels abort_at= h->has_rollback() ? - THD_ABORT_SOFTLY : THD_ABORT_ASAP; - if (thd_kill_level(thd) > abort_at) - return CHECK_ABORTED_BY_USER; - if (h->end_range && h->compare_key2(h->end_range) > 0) + enum thd_kill_levels killed= thd_kill_level(thd); + if (unlikely(killed != THD_IS_NOT_KILLED)) + { + enum thd_kill_levels abort_at= (h->has_transactions() ? + THD_ABORT_SOFTLY : + THD_ABORT_ASAP); + if (killed > abort_at) + return CHECK_ABORTED_BY_USER; + } + if (unlikely(h->end_range) && h->compare_key2(h->end_range) > 0) return CHECK_OUT_OF_RANGE; h->increment_statistics(&SSV::ha_icp_attempts); - if ((res= h->pushed_idx_cond->val_int()? CHECK_POS : CHECK_NEG) == - CHECK_POS) - h->increment_statistics(&SSV::ha_icp_match); + res= CHECK_NEG; + if (h->pushed_idx_cond->val_int()) + { + res= CHECK_POS; + h->fast_increment_statistics(&SSV::ha_icp_match); + } return res; } @@ -6783,17 +6940,23 @@ check_result_t handler_rowid_filter_check(void *h_arg) { THD *thd= h->table->in_use; DEBUG_SYNC(thd, "handler_rowid_filter_check"); - enum thd_kill_levels abort_at= h->has_transactions() ? - THD_ABORT_SOFTLY : THD_ABORT_ASAP; - if (thd_kill_level(thd) > abort_at) - return CHECK_ABORTED_BY_USER; + + enum thd_kill_levels killed= thd_kill_level(thd); + if (unlikely(killed != THD_IS_NOT_KILLED)) + { + enum thd_kill_levels abort_at= (h->has_transactions() ? + THD_ABORT_SOFTLY : + THD_ABORT_ASAP); + if (killed > abort_at) + return CHECK_ABORTED_BY_USER; + } if (h->end_range && h->compare_key2(h->end_range) > 0) return CHECK_OUT_OF_RANGE; } h->position(tab->record[0]); - return h->pushed_rowid_filter->check((char*)h->ref)? CHECK_POS: CHECK_NEG; + return h->pushed_rowid_filter->check((char*)h->ref) ? CHECK_POS: CHECK_NEG; } @@ -6804,8 +6967,7 @@ check_result_t handler_rowid_filter_check(void *h_arg) extern "C" int handler_rowid_filter_is_active(void *h_arg) { - if (!h_arg) - return false; + DBUG_ASSERT(h_arg); handler *h= (handler*) h_arg; return h->rowid_filter_is_active; } @@ -8716,3 +8878,21 @@ Table_scope_and_contents_source_st::fix_period_fields(THD *thd, } return false; } + +/* + Copy upper level cost to the engine as part of start statement + + This is needed to provide fast access to these variables during + optimization (as we refer to them multiple times during one query). + + The other option would be to access them from THD, but that would + require a function call (as we cannot easily access THD from an + inline handler function) and two extra memory accesses for each + variable. +*/ + +void handler::set_optimizer_costs(THD *thd) +{ + optimizer_where_cost= thd->variables.optimizer_where_cost; + optimizer_scan_setup_cost= thd->variables.optimizer_scan_setup_cost; +} diff --git a/sql/handler.h b/sql/handler.h index 6b05da2ca98..41bc50e52d4 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -28,6 +28,7 @@ #include "sql_const.h" #include "sql_basic_types.h" #include "mysqld.h" /* server_id */ +#include "optimizer_costs.h" #include "sql_plugin.h" /* plugin_ref, st_plugin_int, plugin */ #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA */ #include "sql_cache.h" @@ -35,6 +36,7 @@ #include "sql_array.h" /* Dynamic_array<> */ #include "mdl.h" #include "vers_string.h" +#include "optimizer_costs.h" #include "sql_analyze_stmt.h" // for Exec_time_tracker @@ -1045,6 +1047,7 @@ enum enum_schema_tables SCH_KEY_CACHES, SCH_KEY_COLUMN_USAGE, SCH_OPEN_TABLES, + SCH_OPTIMIZER_COSTS, SCH_OPT_TRACE, SCH_PARAMETERS, SCH_PARTITIONS, @@ -1495,6 +1498,10 @@ struct handlerton /* Called for all storage handlers after ddl recovery is done */ void (*signal_ddl_recovery_done)(handlerton *hton); + /* Called at startup to update default engine costs */ + void (*update_optimizer_costs)(OPTIMIZER_COSTS *costs); + void *optimizer_costs; /* Costs are stored here */ + /* Optional clauses in the CREATE/ALTER TABLE */ @@ -2770,113 +2777,121 @@ typedef struct st_range_seq_if typedef bool (*SKIP_INDEX_TUPLE_FUNC) (range_seq_t seq, range_id_t range_info); +#define MARIADB_NEW_COST_MODEL 1 +/* Separated costs for IO and CPU */ + +struct IO_AND_CPU_COST +{ + double io; + double cpu; + + void add(IO_AND_CPU_COST cost) + { + io+= cost.io; + cpu+= cost.cpu; + } +}; + +/* Cost for reading a row through an index */ +struct ALL_READ_COST +{ + IO_AND_CPU_COST index_cost, row_cost; + longlong max_index_blocks, max_row_blocks; + /* index_only_read = index_cost + copy_cost */ + double copy_cost; + + void reset() + { + row_cost= {0,0}; + index_cost= {0,0}; + max_index_blocks= max_row_blocks= 0; + copy_cost= 0.0; + } +}; + + class Cost_estimate { public: - double io_count; /* number of I/O to fetch records */ double avg_io_cost; /* cost of an average I/O oper. to fetch records */ - double idx_io_count; /* number of I/O to read keys */ - double idx_avg_io_cost; /* cost of an average I/O oper. to fetch records */ - double cpu_cost; /* total cost of operations in CPU */ - double idx_cpu_cost; /* cost of operations in CPU for index */ - double import_cost; /* cost of remote operations */ - double mem_cost; /* cost of used memory */ + double cpu_cost; /* Cpu cost unrelated to engine costs */ + double comp_cost; /* Cost of comparing found rows with WHERE clause */ + double copy_cost; /* Copying the data to 'record' */ + double limit_cost; /* Total cost when restricting rows with limit */ - static constexpr double IO_COEFF= 1; - static constexpr double CPU_COEFF= 1; - static constexpr double MEM_COEFF= 1; - static constexpr double IMPORT_COEFF= 1; + IO_AND_CPU_COST index_cost; + IO_AND_CPU_COST row_cost; Cost_estimate() { reset(); } + /* + Total cost for the range + Note that find_cost() + compare_cost() + data_copy_cost() == total_cost() + */ + double total_cost() const { - return IO_COEFF*io_count*avg_io_cost + - IO_COEFF*idx_io_count*idx_avg_io_cost + - CPU_COEFF*(cpu_cost + idx_cpu_cost) + - MEM_COEFF*mem_cost + IMPORT_COEFF*import_cost; + return ((index_cost.io + row_cost.io) * avg_io_cost+ + index_cost.cpu + row_cost.cpu + comp_cost + copy_cost + + cpu_cost); } - double index_only_cost() + /* Cost for just fetching and copying a row (no compare costs) */ + double fetch_cost() const { - return IO_COEFF*idx_io_count*idx_avg_io_cost + - CPU_COEFF*idx_cpu_cost; + return ((index_cost.io + row_cost.io) * avg_io_cost+ + index_cost.cpu + row_cost.cpu + copy_cost); } - /** - Whether or not all costs in the object are zero - - @return true if all costs are zero, false otherwise + /* + Cost of copying the row or key to 'record' */ - bool is_zero() const + inline double data_copy_cost() const { - return io_count == 0.0 && idx_io_count == 0.0 && cpu_cost == 0.0 && - import_cost == 0.0 && mem_cost == 0.0; + return copy_cost; } - void reset() + /* + Multiply costs to simulate a scan where we read + We assume that io blocks will be cached and we only + allocate memory once. There should also be no import_cost + that needs to be done multiple times + */ + void multiply(uint n) { - avg_io_cost= 1.0; - idx_avg_io_cost= 1.0; - io_count= idx_io_count= cpu_cost= idx_cpu_cost= mem_cost= import_cost= 0.0; + index_cost.io*= n; + index_cost.cpu*= n; + row_cost.io*= n; + row_cost.cpu*= n; + copy_cost*= n; + comp_cost*= n; + cpu_cost*= n; } - void multiply(double m) + void add(Cost_estimate *cost) { - io_count *= m; - cpu_cost *= m; - idx_io_count *= m; - idx_cpu_cost *= m; - import_cost *= m; - /* Don't multiply mem_cost */ + avg_io_cost= cost->avg_io_cost; + index_cost.io+= cost->index_cost.io; + index_cost.cpu+= cost->index_cost.cpu; + row_cost.io+= cost->row_cost.io; + row_cost.cpu+= cost->row_cost.cpu; + copy_cost+= cost->copy_cost; + comp_cost+= cost->comp_cost; + cpu_cost+= cost->cpu_cost; } - void add(const Cost_estimate* cost) + inline void reset() { - if (cost->io_count != 0.0) - { - double io_count_sum= io_count + cost->io_count; - avg_io_cost= (io_count * avg_io_cost + - cost->io_count * cost->avg_io_cost) - /io_count_sum; - io_count= io_count_sum; - } - if (cost->idx_io_count != 0.0) - { - double idx_io_count_sum= idx_io_count + cost->idx_io_count; - idx_avg_io_cost= (idx_io_count * idx_avg_io_cost + - cost->idx_io_count * cost->idx_avg_io_cost) - /idx_io_count_sum; - idx_io_count= idx_io_count_sum; - } - cpu_cost += cost->cpu_cost; - idx_cpu_cost += cost->idx_cpu_cost; - import_cost += cost->import_cost; + avg_io_cost= 0; + comp_cost= cpu_cost= 0.0; + copy_cost= limit_cost= 0.0; + index_cost= {0,0}; + row_cost= {0,0}; } - - void add_io(double add_io_cnt, double add_avg_cost) - { - /* In edge cases add_io_cnt may be zero */ - if (add_io_cnt > 0) - { - double io_count_sum= io_count + add_io_cnt; - avg_io_cost= (io_count * avg_io_cost + - add_io_cnt * add_avg_cost) / io_count_sum; - io_count= io_count_sum; - } - } - - /// Add to CPU cost - void add_cpu(double add_cpu_cost) { cpu_cost+= add_cpu_cost; } - - /// Add to import cost - void add_import(double add_import_cost) { import_cost+= add_import_cost; } - - /// Add to memory cost - void add_mem(double add_mem_cost) { mem_cost+= add_mem_cost; } + inline void reset(handler *file); /* To be used when we go from old single value-based cost calculations to @@ -2885,13 +2900,10 @@ public: void convert_from_cost(double cost) { reset(); - io_count= cost; + cpu_cost= cost; } }; -void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, - Cost_estimate *cost); - /* Indicates that all scanned ranges will be singlepoint (aka equality) ranges. The ranges may not use the full key but all of them will use the same number @@ -3065,6 +3077,7 @@ enum class Compare_keys : uint32_t NotEqual }; + /** The handler class is the interface for dynamically loadable storage engines. Do not add ifdefs and take care when adding or @@ -3125,9 +3138,10 @@ protected: ha_rows estimation_rows_to_insert; handler *lookup_handler; public: - handlerton *ht; /* storage engine of this handler */ - uchar *ref; /* Pointer to current row */ - uchar *dup_ref; /* Pointer to duplicate row */ + handlerton *ht; /* storage engine of this handler */ + OPTIMIZER_COSTS *costs; /* Points to table->share->costs */ + uchar *ref; /* Pointer to current row */ + uchar *dup_ref; /* Pointer to duplicate row */ uchar *lookup_buffer; ha_statistics stats; @@ -3138,6 +3152,7 @@ public: HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */ uint ranges_in_seq; /* Total number of ranges in the traversed sequence */ /** Current range (the one we're now returning rows from) */ + KEY_MULTI_RANGE mrr_cur_range; /** The following are for read_range() */ @@ -3318,13 +3333,15 @@ private: For non partitioned handlers this is &TABLE_SHARE::ha_share. */ Handler_share **ha_share; + double optimizer_where_cost; // Copy of THD->...optimzer_where_cost + double optimizer_scan_setup_cost; // Copy of THD->...optimzer_scan_... public: handler(handlerton *ht_arg, TABLE_SHARE *share_arg) :table_share(share_arg), table(0), estimation_rows_to_insert(0), lookup_handler(this), - ht(ht_arg), ref(0), lookup_buffer(NULL), end_range(NULL), + ht(ht_arg), costs(0), ref(0), lookup_buffer(NULL), end_range(NULL), implicit_emptied(0), mark_trx_read_write_done(0), check_table_binlog_row_based_done(0), @@ -3348,12 +3365,19 @@ public: m_psi_numrows(0), m_psi_locker(NULL), row_logging(0), row_logging_init(0), - m_lock_type(F_UNLCK), ha_share(NULL) + m_lock_type(F_UNLCK), ha_share(NULL), optimizer_where_cost(0), + optimizer_scan_setup_cost(0) { DBUG_PRINT("info", ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d", F_UNLCK, F_RDLCK, F_WRLCK)); reset_statistics(); + /* + The following variables should be updated in set_optimizer_costs() + which is to be run as part of setting up the table for the query + */ + MEM_UNDEFINED(&optimizer_where_cost, sizeof(optimizer_where_cost)); + MEM_UNDEFINED(&optimizer_scan_setup_cost, sizeof(optimizer_scan_setup_cost)); } virtual ~handler(void) { @@ -3456,14 +3480,15 @@ public: int ha_delete_row(const uchar * buf); void ha_release_auto_increment(); - bool keyread_enabled() { return keyread < MAX_KEY; } - int ha_start_keyread(uint idx) + inline bool keyread_enabled() { return keyread < MAX_KEY; } + inline int ha_start_keyread(uint idx) { - int res= keyread_enabled() ? 0 : extra_opt(HA_EXTRA_KEYREAD, idx); + if (keyread_enabled()) + return 0; keyread= idx; - return res; + return extra_opt(HA_EXTRA_KEYREAD, idx); } - int ha_end_keyread() + inline int ha_end_keyread() { if (!keyread_enabled()) return 0; @@ -3553,51 +3578,250 @@ public: bzero(©_info, sizeof(copy_info)); reset_copy_info(); } - virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) + virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share); + + inline double io_cost(IO_AND_CPU_COST cost) { - table= table_arg; - table_share= share; - reset_statistics(); - } - virtual double scan_time() - { - return ((ulonglong2double(stats.data_file_length) / stats.block_size + 2) * - avg_io_cost()); + return cost.io * DISK_READ_COST * DISK_READ_RATIO; } - virtual double key_scan_time(uint index) + inline double cost(IO_AND_CPU_COST cost) { - return keyread_time(index, 1, records()); + return io_cost(cost) + cost.cpu; } - virtual double avg_io_cost() + /* + Calculate cost with capping io_blocks to the given maximum. + This is done here instead of earlier to allow filtering to work + with the original' io_block counts. + */ + inline double cost(ALL_READ_COST *cost) { - return 1.0; + double blocks= (MY_MIN(cost->index_cost.io,(double) cost->max_index_blocks) + + MY_MIN(cost->row_cost.io, (double) cost->max_row_blocks)); + return ((cost->index_cost.cpu + cost->row_cost.cpu + cost->copy_cost) + + blocks * DISK_READ_COST * DISK_READ_RATIO); + } + + /* + Calculate cost when we are going to excute the given read method + multiple times + */ + inline double cost_for_reading_multiple_times(double multiple, + ALL_READ_COST *cost) + + { + double blocks= (MY_MIN(cost->index_cost.io * multiple, + (double) cost->max_index_blocks) + + MY_MIN(cost->row_cost.io * multiple, + (double) cost->max_row_blocks)); + return ((cost->index_cost.cpu + cost->row_cost.cpu + cost->copy_cost) * + multiple + + blocks * DISK_READ_COST * DISK_READ_RATIO); + } + + inline ulonglong row_blocks() + { + return (stats.data_file_length + IO_SIZE-1) / IO_SIZE; + } + + virtual ulonglong index_blocks(uint index, uint ranges, ha_rows rows); + + inline ulonglong index_blocks(uint index) + { + return index_blocks(index, 1, stats.records); + } + + /* + Time for a full table data scan. To be overrided by engines, should not + be used by the sql level. + */ +protected: + virtual IO_AND_CPU_COST scan_time() + { + IO_AND_CPU_COST cost; + ulonglong length= stats.data_file_length; + cost.io= (double) (length / IO_SIZE); + cost.cpu= (!stats.block_size ? 0.0 : + (double) ((length + stats.block_size-1)/stats.block_size) * + INDEX_BLOCK_COPY_COST); + return cost; + } +public: + + /* + Time for a full table scan + + @param records Number of records from the engine or records from + status tables stored by ANALYZE TABLE. + + The TABLE_SCAN_SETUP_COST is there to prefer range scans to full + table scans. This is mainly to make the test suite happy as + many tests has very few rows. In real life tables has more than + a few rows and the extra cost has no practical effect. + */ + + inline IO_AND_CPU_COST ha_scan_time(ha_rows rows) + { + IO_AND_CPU_COST cost= scan_time(); + cost.cpu+= (TABLE_SCAN_SETUP_COST + + (double) rows * (ROW_NEXT_FIND_COST + ROW_COPY_COST)); + return cost; + } + + /* + Time for a full table scan, fetching the rows from the table and comparing + the row with the where clause + */ + inline IO_AND_CPU_COST ha_scan_and_compare_time(ha_rows rows) + { + IO_AND_CPU_COST cost= ha_scan_time(rows); + cost.cpu+= (double) rows * WHERE_COST; + return cost; + } + + /* + Update table->share optimizer costs for this particular table. + Called once when table is opened the first time. + */ + virtual void update_optimizer_costs(OPTIMIZER_COSTS *costs) {} + + /* + Set handler optimizer cost variables. + Called for each table used by the statment + This is virtual mainly for the partition engine. + */ + virtual void set_optimizer_costs(THD *thd); + +protected: + /* + Cost of reading 'rows' number of rows with a rowid + */ + virtual IO_AND_CPU_COST rnd_pos_time(ha_rows rows) + { + double r= rows2double(rows); + return + { + r * ((stats.block_size + IO_SIZE -1 )/IO_SIZE), // Blocks read + r * INDEX_BLOCK_COPY_COST // Copy block from cache + }; + } +public: + + /* + Time for doing and internal rnd_pos() inside the engine. For some + engine, this is more efficient than the SQL layer calling + rnd_pos() as there is no overhead in converting/checking the + rnd_pos_value. This is used when calculating the cost of fetching + a key+row in one go (like when scanning an index and fetching the + row). + */ + + inline IO_AND_CPU_COST ha_rnd_pos_time(ha_rows rows) + { + IO_AND_CPU_COST cost= rnd_pos_time(rows); + set_if_smaller(cost.io, (double) row_blocks()); + cost.cpu+= rows2double(rows) * (ROW_LOOKUP_COST + ROW_COPY_COST); + return cost; + } + + /* + This cost if when we are calling rnd_pos() explict in the call + For the moment this function is identical to ha_rnd_pos time, + but that may change in the future after we do more cost checks for + more engines. + */ + inline IO_AND_CPU_COST ha_rnd_pos_call_time(ha_rows rows) + { + IO_AND_CPU_COST cost= rnd_pos_time(rows); + set_if_smaller(cost.io, (double) row_blocks()); + cost.cpu+= rows2double(rows) * (ROW_LOOKUP_COST + ROW_COPY_COST); + return cost; + } + + inline IO_AND_CPU_COST ha_rnd_pos_call_and_compare_time(ha_rows rows) + { + IO_AND_CPU_COST cost; + cost= ha_rnd_pos_call_time(rows); + cost.cpu+= rows2double(rows) * WHERE_COST; + return cost; } /** - The cost of reading a set of ranges from the table using an index - to access it. - - @param index The index number. - @param ranges The number of ranges to be read. If 0, it means that - we calculate separately the cost of reading the key. - @param rows Total number of rows to be read. - - This method can be used to calculate the total cost of scanning a table - using an index by calling it using read_time(index, 1, table_size). - */ - virtual double read_time(uint index, uint ranges, ha_rows rows) - { return rows2double(ranges+rows); } + Calculate cost of 'index_only' scan for given index, a number of ranges + and number of records. - /** - Calculate cost of 'keyread' scan for given index and number of records. - - @param index index to read - @param ranges #of ranges to read - @param rows #of records to read + @param index Index to read + @param rows #of records to read + @param blocks Number of IO blocks that needs to be accessed. + 0 if not known (in which case it's calculated) */ - virtual double keyread_time(uint index, uint ranges, ha_rows rows); +protected: + virtual IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks); +public: + + /* + Calculate cost of 'keyread' scan for given index and number of records + including fetching the key to the 'record' buffer. + */ + IO_AND_CPU_COST ha_keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks); + + /* Same as above, but take into account copying the key the the SQL layer */ + inline IO_AND_CPU_COST ha_keyread_and_copy_time(uint index, ulong ranges, + ha_rows rows, + ulonglong blocks) + { + IO_AND_CPU_COST cost= ha_keyread_time(index, ranges, rows, blocks); + cost.cpu+= (double) rows * KEY_COPY_COST; + return cost; + } + + inline IO_AND_CPU_COST ha_keyread_and_compare_time(uint index, ulong ranges, + ha_rows rows, + ulonglong blocks) + { + IO_AND_CPU_COST cost= ha_keyread_time(index, ranges, rows, blocks); + cost.cpu+= (double) rows * (KEY_COPY_COST + WHERE_COST); + return cost; + } + + IO_AND_CPU_COST ha_keyread_clustered_time(uint index, + ulong ranges, + ha_rows rows, + ulonglong blocks); + /* + Time for a full table index scan (without copy or compare cost). + To be overrided by engines, sql level should use ha_key_scan_time(). + Note that IO_AND_CPU_COST does not include avg_io_cost() ! + */ +protected: + virtual IO_AND_CPU_COST key_scan_time(uint index, ha_rows rows) + { + return keyread_time(index, 1, MY_MAX(rows, 1), 0); + } +public: + + /* Cost of doing a full index scan */ + inline IO_AND_CPU_COST ha_key_scan_time(uint index, ha_rows rows) + { + IO_AND_CPU_COST cost= key_scan_time(index, rows); + cost.cpu+= (INDEX_SCAN_SETUP_COST + KEY_LOOKUP_COST + + (double) rows * (KEY_NEXT_FIND_COST + KEY_COPY_COST)); + return cost; + } + + /* + Cost of doing a full index scan with record copy and compare + @param rows Rows from stat tables + */ + inline IO_AND_CPU_COST ha_key_scan_and_compare_time(uint index, ha_rows rows) + { + IO_AND_CPU_COST cost= ha_key_scan_time(index, rows); + cost.cpu+= (double) rows * WHERE_COST; + return cost; + } virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; } @@ -3902,7 +4126,7 @@ public: virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *mrr_mode, + uint *mrr_mode, ha_rows limit, Cost_estimate *cost); virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, uint key_parts, uint *bufsz, @@ -3911,6 +4135,13 @@ public: uint n_ranges, uint mrr_mode, HANDLER_BUFFER *buf); virtual int multi_range_read_next(range_id_t *range_info); +private: + inline void calculate_costs(Cost_estimate *cost, uint keyno, + uint ranges, uint multi_row_ranges, uint flags, + ha_rows total_rows, + ulonglong io_blocks, + ulonglong unassigned_single_point_ranges); +public: /* Return string representation of the MRR plan. @@ -4317,6 +4548,7 @@ public: For a clustered (primary) key, the following should also hold: index_flags() should contain HA_CLUSTERED_INDEX + index_flags() should not contain HA_KEYREAD_ONLY or HA_DO_RANGE_FILTER_PUSHDOWN table_flags() should contain HA_TABLE_SCAN_ON_INDEX For a reference key the following should also hold: @@ -4327,20 +4559,9 @@ public: */ /* The following code is for primary keys */ - bool pk_is_clustering_key(uint index) const - { - /* - We have to check for MAX_INDEX as table->s->primary_key can be - MAX_KEY in the case where there is no primary key. - */ - return index != MAX_KEY && is_clustering_key(index); - } + inline bool pk_is_clustering_key(uint index) const; /* Same as before but for other keys, in which case we can skip the check */ - bool is_clustering_key(uint index) const - { - DBUG_ASSERT(index != MAX_KEY); - return (index_flags(index, 0, 1) & HA_CLUSTERED_INDEX); - } + inline bool is_clustering_key(uint index) const; virtual int cmp_ref(const uchar *ref1, const uchar *ref2) { @@ -4423,7 +4644,11 @@ public: virtual void cancel_pushed_rowid_filter() { pushed_rowid_filter= NULL; - rowid_filter_is_active= false; + if (rowid_filter_is_active) + { + rowid_filter_is_active= false; + rowid_filter_changed(); + } } virtual void disable_pushed_rowid_filter() @@ -4431,10 +4656,14 @@ public: DBUG_ASSERT(pushed_rowid_filter != NULL && save_pushed_rowid_filter == NULL); save_pushed_rowid_filter= pushed_rowid_filter; - if (rowid_filter_is_active) - save_rowid_filter_is_active= rowid_filter_is_active; + save_rowid_filter_is_active= rowid_filter_is_active; pushed_rowid_filter= NULL; - rowid_filter_is_active= false; + + if (rowid_filter_is_active) + { + rowid_filter_is_active= false; + rowid_filter_changed(); + } } virtual void enable_pushed_rowid_filter() @@ -4442,12 +4671,17 @@ public: DBUG_ASSERT(save_pushed_rowid_filter != NULL && pushed_rowid_filter == NULL); pushed_rowid_filter= save_pushed_rowid_filter; - if (save_rowid_filter_is_active) - rowid_filter_is_active= true; save_pushed_rowid_filter= NULL; + if (save_rowid_filter_is_active) + { + rowid_filter_is_active= true; + rowid_filter_changed(); + } } virtual bool rowid_filter_push(Rowid_filter *rowid_filter) { return true; } + /* Signal that rowid filter may have been enabled / disabled */ + virtual void rowid_filter_changed() {} /* Needed for partition / spider */ virtual TABLE_LIST *get_next_global_for_child() { return NULL; } @@ -4767,7 +5001,6 @@ private: } } -private: void mark_trx_read_write_internal(); bool check_table_binlog_row_based_internal(); @@ -4785,7 +5018,13 @@ protected: However, engines that implement read_range_XXX() (like MariaRocks) or embed other engines (like ha_partition) may need to call these also */ + /* + Increment statistics. As a side effect increase accessed_rows_and_keys + and checks if lex->limit_rows_examined_cnt is reached + */ inline void increment_statistics(ulong SSV::*offset) const; + /* Same as increment_statistics but doesn't increase accessed_rows_and_keys */ + inline void fast_increment_statistics(ulong SSV::*offset) const; inline void decrement_statistics(ulong SSV::*offset) const; private: @@ -5044,7 +5283,7 @@ public: ha_share= arg_ha_share; return false; } - void set_table(TABLE* table_arg) { table= table_arg; } + inline void set_table(TABLE* table_arg); int get_lock_type() const { return m_lock_type; } public: /* XXX to be removed, see ha_partition::partition_ht() */ @@ -5116,6 +5355,12 @@ protected: void set_ha_share_ptr(Handler_share *arg_ha_share); void lock_shared_ha_data(); void unlock_shared_ha_data(); + + /* + Mroonga needs to call some xxx_time() directly for it's internal handler + methods + */ + friend class ha_mroonga; }; #include "multi_range_read.h" @@ -5390,4 +5635,10 @@ uint ha_count_rw_2pc(THD *thd, bool all); uint ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, bool all); +inline void Cost_estimate::reset(handler *file) +{ + reset(); + avg_io_cost= file->DISK_READ_COST * file->DISK_READ_RATIO; +} + #endif /* HANDLER_INCLUDED */ diff --git a/sql/item.cc b/sql/item.cc index 5bcddb5cd67..ce55d77eb4d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -42,6 +42,7 @@ // RESOLVED_AGAINST_ALIAS, ... #include "sql_expression_cache.h" #include "sql_lex.h" // empty_clex_str +#include "my_json_writer.h" // for dbug_print_opt_trace() const String my_null_string("NULL", 4, default_charset_info); const String my_default_string("DEFAULT", 7, default_charset_info); @@ -411,7 +412,7 @@ int Item::save_str_value_in_field(Field *field, String *result) Item::Item(THD *thd): - name(null_clex_str), orig_name(0), is_expensive_cache(-1) + name(null_clex_str), orig_name(null_clex_str), is_expensive_cache(-1) { DBUG_ASSERT(thd); base_flags= item_base_t::FIXED; @@ -444,7 +445,7 @@ Item::Item(THD *thd): */ Item::Item(): - name(null_clex_str), orig_name(0), is_expensive_cache(-1) + name(null_clex_str), orig_name(null_clex_str), is_expensive_cache(-1) { DBUG_ASSERT(!mysqld_server_started); // Created early base_flags= item_base_t::FIXED; @@ -552,11 +553,8 @@ void Item::cleanup() DBUG_PRINT("enter", ("this: %p", this)); marker= MARKER_UNUSED; join_tab_idx= MAX_TABLES; - if (orig_name) - { - name.str= orig_name; - name.length= strlen(orig_name); - } + if (orig_name.str) + name= orig_name; DBUG_VOID_RETURN; } @@ -6348,6 +6346,24 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal) } +/* + Check if field is is equal to current field or any of the fields in + item_equal +*/ + +bool Item_field::contains(Field *field_arg) +{ + if (field == field_arg) + return 1; + /* + Check if there is a multiple equality that allows to infer that field + (see also: compute_part_of_sort_key_for_equals) + */ + if (item_equal && item_equal->contains(field_arg)) + return 1; + return 0; +} + /** Set a pointer to the multiple equality the field reference belongs to (if any). @@ -10872,6 +10888,29 @@ const char *dbug_print_item(Item *item) return "Couldn't fit into buffer"; } + +/* + Return the optimizer trace collected so far for the current thread. +*/ + +const char *dbug_print_opt_trace() +{ + if (current_thd) + { + if (current_thd->opt_trace.is_started()) + { + String *s= const_cast(current_thd->opt_trace + .get_current_json()->output.get_string()); + return s->c_ptr(); + } + else + return "Trace empty"; + } + else + return "No Thread"; +} + + const char *dbug_print_select(SELECT_LEX *sl) { char *buf= dbug_item_print_buf; diff --git a/sql/item.h b/sql/item.h index 706360c48f1..e15d454c65f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1035,7 +1035,7 @@ public: LEX_CSTRING name; /* Name of item */ /* Original item name (if it was renamed)*/ - const char *orig_name; + LEX_CSTRING orig_name; /* All common bool variables for an Item is stored here */ item_base_t base_flags; @@ -3786,6 +3786,7 @@ public: Item_equal *get_item_equal() override { return item_equal; } void set_item_equal(Item_equal *item_eq) override { item_equal= item_eq; } Item_equal *find_item_equal(COND_EQUAL *cond_equal) override; + bool contains(Field *field); Item* propagate_equal_fields(THD *, const Context &, COND_EQUAL *) override; Item *replace_equal_field(THD *thd, uchar *arg) override; uint32 max_display_length() const override diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 9b4e60b4086..f8e6a13ce97 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -42,6 +42,7 @@ #include "sql_parse.h" // check_stack_overrun #include "sql_cte.h" #include "sql_test.h" +#include "opt_trace.h" double get_post_group_estimate(JOIN* join, double join_op_rows); @@ -1588,8 +1589,9 @@ Item_exists_subselect::Item_exists_subselect(THD *thd, { DBUG_ENTER("Item_exists_subselect::Item_exists_subselect"); - init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this)); + select_lex->distinct= 1; + select_lex->master_unit()->distinct= 1; max_columns= UINT_MAX; null_value= FALSE; //can't be NULL base_flags&= ~item_base_t::MAYBE_NULL; //can't be NULL @@ -1640,6 +1642,39 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp, Item_row(thd, static_cast(left_exp)); func= &eq_creator; init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this)); + select_lex->distinct= 1; + + /* + If the IN subquery (xxx IN (SELECT ...) is a join without grouping, + we don't need duplicates from the tables it is joining. These + tables can be derived tables, like shown in the following + example. In this case, it's useful to indicate that we don't need + duplicates from them either. + + Example: + col IN (SELECT ... -- this is the select_lex + FROM + (SELECT ... FROM t1) AS t1, -- child1, first_inner_init(). + (SELECT ... FROM t2) AS t2, -- child2 + WHERE + ... + ) + + We don't need duplicates from either child1 or child2. + We only indicate this to child1 (select_lex->first_inner_unit()), as that + catches most of practically important use cases. + + (The check for item==NULL is to make sure the subquery is a derived table + and not any other kind of subquery like another IN (SELECT ...) or a scalar- + context (SELECT 'foo')) + */ + + select_lex->master_unit()->distinct= 1; + if (!select_lex->with_sum_func && + select_lex->first_inner_unit() && + select_lex->first_inner_unit()->item == NULL) + select_lex->first_inner_unit()->distinct= 1; + max_columns= UINT_MAX; set_maybe_null(); reset(); @@ -1667,6 +1702,16 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp, Item_row(thd, static_cast(left_exp)); func= func_creator(all_arg); init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this)); + select_lex->distinct= 1; + /* + If this is is 'xxx IN (SELECT ...) mark that the we are only interested in + unique values for the select + */ + select_lex->master_unit()->distinct= 1; + if (!select_lex->with_sum_func && + select_lex->first_inner_unit() && + select_lex->first_inner_unit()->item == NULL) + select_lex->first_inner_unit()->distinct= 1; max_columns= 1; reset(); //if test_limit will fail then error will be reported to client @@ -3298,6 +3343,14 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg) set possible optimization strategies */ in_subs->emb_on_expr_nest= emb_on_expr_nest; + + { + OPT_TRACE_TRANSFORM(thd, trace_wrapper, trace_transform, + in_subs->get_select_lex()->select_number, + "EXISTS (SELECT)", "IN (SELECT)"); + trace_transform.add( "upper_not", ( upper_not?true:false ) ); + } + res= check_and_do_in_subquery_rewrites(join); first_select->join->prepare_stage2(); diff --git a/sql/json_table.cc b/sql/json_table.cc index 05ee83bd3d8..d404a54bc3f 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -54,6 +54,7 @@ public: bzero(&m_hton, sizeof(m_hton)); m_hton.tablefile_extensions= hton_no_exts; m_hton.slot= HA_SLOT_UNDEF; + m_hton.flags= HTON_HIDDEN; } }; @@ -245,6 +246,10 @@ public: int open(const char *name, int mode, uint test_if_locked) override { return 0; } int close(void) override { return 0; } + void update_optimizer_costs(OPTIMIZER_COSTS *costs) override + { + memcpy(costs, &heap_optimizer_costs, sizeof(*costs)); + } int rnd_init(bool scan) override; int rnd_next(uchar *buf) override; int rnd_pos(uchar * buf, uchar *pos) override; diff --git a/sql/keycaches.cc b/sql/keycaches.cc index 10bec7c1de8..250a287e229 100644 --- a/sql/keycaches.cc +++ b/sql/keycaches.cc @@ -15,6 +15,10 @@ #include "mariadb.h" #include "keycaches.h" +#include "optimizer_costs.h" +#include "optimizer_defaults.h" +#include "handler.h" +#include "sql_class.h" /**************************************************************************** Named list handling @@ -22,10 +26,13 @@ NAMED_ILIST key_caches; NAMED_ILIST rpl_filters; +NAMED_ILIST linked_optimizer_costs; extern "C" PSI_memory_key key_memory_KEY_CACHE; extern PSI_memory_key key_memory_NAMED_ILINK_name; +LEX_CSTRING default_base= {STRING_WITH_LEN("default")}; + /** ilink (intrusive list element) with a name */ @@ -46,7 +53,7 @@ public: } inline bool cmp(const char *name_cmp, size_t length) { - return length == name_length && !memcmp(name, name_cmp, length); + return !system_charset_info->strnncoll(name, name_length, name_cmp, length); } ~NAMED_ILINK() { @@ -72,7 +79,8 @@ uchar* find_named(I_List *list, const char *name, size_t length, } -bool NAMED_ILIST::delete_element(const char *name, size_t length, void (*free_element)(const char *name, void*)) +bool NAMED_ILIST::delete_element(const char *name, size_t length, + void (*free_element)(const char *name, void*)) { I_List_iterator it(*this); NAMED_ILINK *element; @@ -104,14 +112,12 @@ void NAMED_ILIST::delete_elements(void (*free_element)(const char *name, void*)) /* Key cache functions */ -LEX_CSTRING default_key_cache_base= {STRING_WITH_LEN("default")}; - KEY_CACHE zero_key_cache; ///< @@nonexistent_cache.param->value_ptr() points here KEY_CACHE *get_key_cache(const LEX_CSTRING *cache_name) { if (!cache_name || ! cache_name->length) - cache_name= &default_key_cache_base; + cache_name= &default_base; return ((KEY_CACHE*) find_named(&key_caches, cache_name->str, cache_name->length, 0)); } @@ -234,3 +240,128 @@ void free_all_rpl_filters() { rpl_filters.delete_elements(free_rpl_filter); } + + +/****************************************************************************** + Optimizer costs functions +******************************************************************************/ + +LEX_CSTRING default_costs_base= {STRING_WITH_LEN("default")}; + +OPTIMIZER_COSTS default_optimizer_costs= +{ + DEFAULT_DISK_READ_COST, // disk_read_cost + DEFAULT_INDEX_BLOCK_COPY_COST, // index_block_copy_cost + DEFAULT_WHERE_COST/4, // key_cmp_cost + DEFAULT_KEY_COPY_COST, // key_copy_cost + DEFAULT_KEY_LOOKUP_COST, // key_lookup_cost + DEFAULT_KEY_NEXT_FIND_COST, // key_next_find_cost + DEFAULT_DISK_READ_RATIO, // disk_read_ratio + DEFAULT_ROW_COPY_COST, // row_copy_cost + DEFAULT_ROW_LOOKUP_COST, // row_lookup_cost + DEFAULT_ROW_NEXT_FIND_COST, // row_next_find_cost + DEFAULT_ROWID_COMPARE_COST, // rowid_compare_cost + DEFAULT_ROWID_COPY_COST, // rowid_copy_cost + 1 // Cannot be deleted +}; + +OPTIMIZER_COSTS heap_optimizer_costs, tmp_table_optimizer_costs; + +OPTIMIZER_COSTS *get_optimizer_costs(const LEX_CSTRING *cache_name) +{ + if (!cache_name->length) + return &default_optimizer_costs; + return ((OPTIMIZER_COSTS*) find_named(&linked_optimizer_costs, + cache_name->str, cache_name->length, + 0)); +} + +OPTIMIZER_COSTS *create_optimizer_costs(const char *name, size_t length) +{ + OPTIMIZER_COSTS *optimizer_costs; + DBUG_ENTER("create_optimizer_costs"); + DBUG_PRINT("enter",("name: %.*s", (int) length, name)); + + if ((optimizer_costs= (OPTIMIZER_COSTS*) + my_malloc(key_memory_KEY_CACHE, + sizeof(OPTIMIZER_COSTS), MYF(MY_ZEROFILL | MY_WME)))) + { + if (!new NAMED_ILINK(&linked_optimizer_costs, name, length, + (uchar*) optimizer_costs)) + { + my_free(optimizer_costs); + optimizer_costs= 0; + } + else + { + /* Mark that values are not yet set */ + for (uint i=0 ; i < sizeof(OPTIMIZER_COSTS)/sizeof(double) ; i++) + ((double*) optimizer_costs)[i]= OPTIMIZER_COST_UNDEF; + } + } + DBUG_RETURN(optimizer_costs); +} + + +OPTIMIZER_COSTS *get_or_create_optimizer_costs(const char *name, size_t length) +{ + LEX_CSTRING optimizer_costs_name; + OPTIMIZER_COSTS *optimizer_costs; + + optimizer_costs_name.str= name; + optimizer_costs_name.length= length; + if (!(optimizer_costs= get_optimizer_costs(&optimizer_costs_name))) + optimizer_costs= create_optimizer_costs(name, length); + return optimizer_costs; +} + +extern "C" +{ +bool process_optimizer_costs(process_optimizer_costs_t func, TABLE *param) +{ + I_List_iterator it(linked_optimizer_costs); + NAMED_ILINK *element; + int res= 0; + + while ((element= it++)) + { + LEX_CSTRING name= { element->name, element->name_length }; + OPTIMIZER_COSTS *costs= (OPTIMIZER_COSTS *) element->data; + res |= func(&name, costs, param); + } + return res != 0; +} +} + +bool create_default_optimizer_costs() +{ + return (new NAMED_ILINK(&linked_optimizer_costs, + default_base.str, default_base.length, + (uchar*) &default_optimizer_costs)) == 0; +} + + +/* + Make a copy of heap and tmp_table engine costs to be able to create + internal temporary tables without taking a mutex. +*/ + +void copy_tmptable_optimizer_costs() +{ + memcpy(&heap_optimizer_costs, heap_hton->optimizer_costs, + sizeof(heap_optimizer_costs)); + memcpy(&tmp_table_optimizer_costs, TMP_ENGINE_HTON->optimizer_costs, + sizeof(tmp_table_optimizer_costs)); +} + + +static void free_optimizer_costs(const char *name, void *cost) +{ + if ((OPTIMIZER_COSTS*) cost != &default_optimizer_costs) + my_free(cost); +} + +void free_all_optimizer_costs() +{ + linked_optimizer_costs.delete_elements(free_optimizer_costs); +} diff --git a/sql/keycaches.h b/sql/keycaches.h index 68c3dd3a2b0..721251b6745 100644 --- a/sql/keycaches.h +++ b/sql/keycaches.h @@ -35,7 +35,7 @@ class NAMED_ILIST: public I_List }; /* For key cache */ -extern LEX_CSTRING default_key_cache_base; +extern LEX_CSTRING default_base; extern KEY_CACHE zero_key_cache; extern NAMED_ILIST key_caches; diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 2701dac56c4..7f930c9d9ae 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -20,6 +20,74 @@ #include "key.h" #include "sql_statistics.h" #include "rowid_filter.h" +#include "optimizer_defaults.h" + +static void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, + Cost_estimate *cost); + + + +/* + The following calculation is the same as in multi_range_read_info() + + @param cost Total cost is stored here + @param keyno Key number + @param n_ranges Number of different ranges + @param multi_row_ranges Number of ranges that are not EQ_REF + @param flags Flags. Only HA_MRR_INDEX_ONLY is used. + @param total_rows Number of rows expected to be read. + @param io_blocks Number of blocks we expect to read for + a not clustered index. + @param unassigned_single_point_ranges + Number of blocks we have not yet read for + a clustered index. +*/ + +void handler::calculate_costs(Cost_estimate *cost, uint keyno, + uint n_ranges, uint multi_row_ranges, + uint flags, + ha_rows total_rows, + ulonglong io_blocks, + ulonglong unassigned_single_point_ranges) +{ + cost->reset(this); + + if (!is_clustering_key(keyno)) + { + cost->index_cost= ha_keyread_time(keyno, n_ranges, + total_rows + multi_row_ranges, + io_blocks); + + if (!(flags & HA_MRR_INDEX_ONLY)) + { + /* ha_rnd_pos_time includes ROW_COPY_COST */ + cost->row_cost= ha_rnd_pos_time(total_rows); + /* Adjust io cost to data size */ + cost->row_cost.io= MY_MIN(cost->row_cost.io, row_blocks()); + } + else + { + /* Index only read */ + cost->copy_cost= rows2double(total_rows) * KEY_COPY_COST; + } + } + else + { + /* Clustered index */ + io_blocks= unassigned_single_point_ranges; + cost->index_cost= ha_keyread_time(keyno, n_ranges, + total_rows + multi_row_ranges, + io_blocks); + cost->copy_cost= rows2double(total_rows) * ROW_COPY_COST; + } + /* Adjust io cost to data size */ + cost->index_cost.io= MY_MIN(cost->index_cost.io, index_blocks(keyno)); + + cost->comp_cost= (rows2double(total_rows) * WHERE_COST + + MULTI_RANGE_READ_SETUP_COST); +} + + /**************************************************************************** * Default MRR implementation (MRR to non-MRR converter) @@ -37,8 +105,8 @@ @param n_ranges_arg Number of ranges in the sequence, or 0 if the caller can't efficiently determine it @param bufsz INOUT IN: Size of the buffer available for use - OUT: Size of the buffer that is expected to be actually - used, or 0 if buffer is not needed. + OUT: Size of the buffer that is expected to be + actually used, or 0 if buffer is not needed. @param flags INOUT A combination of HA_MRR_* flags @param cost OUT Estimated cost of MRR access @@ -56,10 +124,12 @@ contain scan parameters. */ + ha_rows handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges_arg, uint *bufsz, uint *flags, + ha_rows top_limit, Cost_estimate *cost) { KEY_MULTI_RANGE range; @@ -286,11 +356,15 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, (single_point_ranges - assigned_single_point_ranges). We don't add these to io_blocks as we don't want to penalize equal - readss (if we did, a range that would read 5 rows would be + reads (if we did, a range that would read 5 rows would be regarded as better than one equal read). Better to assume we have done a records_in_range() for the equal range and it's also cached. + + One effect of this is that io_blocks for simple ranges are often 0, + as the blocks where already read by records_in_range and we assume + that we don't have to read it again. */ io_blocks= (range_blocks_cnt - edge_blocks_cnt); unassigned_single_point_ranges+= (single_point_ranges - @@ -299,41 +373,33 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, if (total_rows != HA_POS_ERROR) { set_if_smaller(total_rows, max_rows); - - /* The following calculation is the same as in multi_range_read_info(): */ *flags |= HA_MRR_USE_DEFAULT_IMPL; - cost->reset(); - cost->avg_io_cost= cost->idx_avg_io_cost= avg_io_cost(); - - if (!is_clustering_key(keyno)) - { - cost->idx_io_count= (double) io_blocks; - cost->idx_cpu_cost= (keyread_time(keyno, 0, total_rows) + - n_ranges * IDX_LOOKUP_COST); - if (!(*flags & HA_MRR_INDEX_ONLY)) - cost->cpu_cost= read_time(keyno, 0, total_rows); - } - else + calculate_costs(cost, keyno, n_ranges, + n_ranges - (uint) single_point_ranges, + *flags, total_rows, + io_blocks, unassigned_single_point_ranges); + if (top_limit < total_rows) { /* - Clustered index - If all index dives are to a few blocks, then limit the - ranges used by read_time to the number of dives. + Calculate what the cost would be if we only have to read 'top_limit' + rows. This is the lowest possible cost when using the range + when we find the 'accepted rows' at once. */ - io_blocks+= unassigned_single_point_ranges; - cost->idx_cpu_cost= n_ranges * IDX_LOOKUP_COST; - uint limited_ranges= (uint) MY_MIN((ulonglong) n_ranges, io_blocks); - cost->cpu_cost= read_time(keyno, limited_ranges, total_rows); + Cost_estimate limit_cost; + calculate_costs(&limit_cost, keyno, n_ranges, + n_ranges - (uint)single_point_ranges, + *flags, top_limit, io_blocks, + unassigned_single_point_ranges); + cost->limit_cost= limit_cost.total_cost(); } - cost->cpu_cost+= (rows2double(total_rows) / TIME_FOR_COMPARE + - MULTI_RANGE_READ_SETUP_COST); + DBUG_PRINT("statistics", + ("key: %s rows: %llu total_cost: %.3f io_blocks: %llu " + "cpu_cost: %.3f", + table->s->keynames.type_names[keyno], + (ulonglong) total_rows, cost->total_cost(), + (ulonglong) (cost->row_cost.io + cost->index_cost.io), + (double) (cost->row_cost.cpu + cost->index_cost.cpu))); } - DBUG_PRINT("statistics", - ("key: %s rows: %llu total_cost: %.3f io_blocks: %llu " - "idx_io_count: %.3f cpu_cost: %.3f io_count: %.3f", - table->s->keynames.type_names[keyno], - (ulonglong) total_rows, cost->total_cost(), (ulonglong) io_blocks, - cost->idx_io_count, cost->cpu_cost, cost->io_count)); DBUG_RETURN(total_rows); } @@ -357,7 +423,7 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, @param keyno Index number @param n_ranges Estimated number of ranges (i.e. intervals) in the range sequence. - @param n_rows Estimated total number of records contained within all + @param total_rows Estimated total number of records contained within all of the ranges @param bufsz INOUT IN: Size of the buffer available for use OUT: Size of the buffer that will be actually used, or @@ -372,7 +438,8 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, other Error or can't perform the requested scan */ -ha_rows handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows, +ha_rows handler::multi_range_read_info(uint keyno, uint n_ranges, + uint total_rows, uint key_parts, uint *bufsz, uint *flags, Cost_estimate *cost) { @@ -385,27 +452,32 @@ ha_rows handler::multi_range_read_info(uint keyno, uint n_ranges, uint n_rows, *bufsz= 0; /* Default implementation doesn't need a buffer */ *flags |= HA_MRR_USE_DEFAULT_IMPL; - cost->reset(); + cost->reset(this); + /* Produce the same cost as non-MRR code does */ if (!is_clustering_key(keyno)) { - /* - idx_io_count could potentially be increased with the number of - index leaf blocks we have to read for finding n_rows. - */ - cost->idx_io_count= n_ranges; - cost->idx_cpu_cost= (keyread_time(keyno, 0, n_rows) + - n_ranges * IDX_LOOKUP_COST); + cost->index_cost= ha_keyread_time(keyno, n_ranges, total_rows, 0); + if (!(*flags & HA_MRR_INDEX_ONLY)) { - cost->cpu_cost= read_time(keyno, 0, n_rows); + /* ha_rnd_pos_time includes ROW_COPY_COST */ + cost->row_cost= ha_rnd_pos_time(total_rows); + } + else + { + /* Index only read */ + cost->copy_cost= rows2double(total_rows) * KEY_COPY_COST; } } else { - cost->cpu_cost= read_time(keyno, n_ranges, (uint)n_rows); + /* Clustering key */ + cost->index_cost= ha_keyread_clustered_time(keyno, n_ranges, total_rows, + 0); + cost->copy_cost= rows2double(total_rows) * ROW_COPY_COST; } - cost->cpu_cost+= rows2double(n_rows) / TIME_FOR_COMPARE; + cost->comp_cost= rows2double(total_rows) * WHERE_COST; return 0; } @@ -1700,8 +1772,9 @@ ha_rows DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows, */ ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq, - void *seq_init_param, uint n_ranges, - uint *bufsz, uint *flags, Cost_estimate *cost) + void *seq_init_param, uint n_ranges, + uint *bufsz, uint *flags, ha_rows limit, + Cost_estimate *cost) { ha_rows rows; uint def_flags= *flags; @@ -1711,7 +1784,9 @@ ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq, seq_init_param, n_ranges, &def_bufsz, - &def_flags, cost); + &def_flags, + limit, + cost); if (rows == HA_POS_ERROR) { /* Default implementation can't perform MRR scan => we can't either */ @@ -1918,7 +1993,8 @@ int DsMrr_impl::dsmrr_explain_info(uint mrr_mode, char *str, size_t size) } -static void get_sort_and_sweep_cost(TABLE *table, ha_rows nrows, Cost_estimate *cost); +static void get_sort_and_sweep_cost(TABLE *table, ha_rows nrows, + Cost_estimate *cost); /** @@ -1949,7 +2025,6 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, ha_rows rows_in_full_step; ha_rows rows_in_last_step; uint n_full_steps; - double index_read_cost; elem_size= primary_file->ref_length + sizeof(void*) * (!MY_TEST(flags & HA_MRR_NO_ASSOCIATION)); @@ -1982,6 +2057,8 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, rows_in_full_step= max_buff_entries; rows_in_last_step= rows % max_buff_entries; + cost->reset(primary_file); + /* Adjust buffer size if we expect to use only part of the buffer */ if (n_full_steps) { @@ -1990,24 +2067,19 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, } else { - cost->reset(); - *buffer_size= (uint)MY_MAX(*buffer_size, - (size_t)(1.2*rows_in_last_step) * elem_size + - primary_file->ref_length + table->key_info[keynr].key_length); + *buffer_size= ((uint) MY_MAX(*buffer_size, + (size_t)(1.2*rows_in_last_step) * elem_size + + primary_file->ref_length + + table->key_info[keynr].key_length)); } Cost_estimate last_step_cost; + last_step_cost.avg_io_cost= cost->avg_io_cost; get_sort_and_sweep_cost(table, rows_in_last_step, &last_step_cost); cost->add(&last_step_cost); - if (n_full_steps != 0) - cost->mem_cost= *buffer_size; - else - cost->mem_cost= (double)rows_in_last_step * elem_size; - /* Total cost of all index accesses */ - index_read_cost= primary_file->keyread_time(keynr, 1, rows); - cost->add_io(index_read_cost, 1 /* Random seeks */); + cost->index_cost= primary_file->ha_keyread_and_copy_time(keynr, 1, rows, 0); return FALSE; } @@ -2031,55 +2103,17 @@ void get_sort_and_sweep_cost(TABLE *table, ha_rows nrows, Cost_estimate *cost) { get_sweep_read_cost(table, nrows, FALSE, cost); /* Add cost of qsort call: n * log2(n) * cost(rowid_comparison) */ - double cmp_op= rows2double(nrows) * (1.0 / TIME_FOR_COMPARE_ROWID); + double cmp_op= rows2double(nrows) * ROWID_COMPARE_COST_THD(table->in_use); if (cmp_op < 3) cmp_op= 3; cost->cpu_cost += cmp_op * log2(cmp_op); } - else - cost->reset(); } /** Get cost of reading nrows table records in a "disk sweep" - A disk sweep read is a sequence of handler->rnd_pos(rowid) calls that made - for an ordered sequence of rowids. - - We assume hard disk IO. The read is performed as follows: - - 1. The disk head is moved to the needed cylinder - 2. The controller waits for the plate to rotate - 3. The data is transferred - - Time to do #3 is insignificant compared to #2+#1. - - Time to move the disk head is proportional to head travel distance. - - Time to wait for the plate to rotate depends on whether the disk head - was moved or not. - - If disk head wasn't moved, the wait time is proportional to distance - between the previous block and the block we're reading. - - If the head was moved, we don't know how much we'll need to wait for the - plate to rotate. We assume the wait time to be a variate with a mean of - 0.5 of full rotation time. - - Our cost units are "random disk seeks". The cost of random disk seek is - actually not a constant, it depends one range of cylinders we're going - to access. We make it constant by introducing a fuzzy concept of "typical - datafile length" (it's fuzzy as it's hard to tell whether it should - include index file, temp.tables etc). Then random seek cost is: - - 1 = half_rotation_cost + move_cost * 1/3 * typical_data_file_length - - We define half_rotation_cost as DISK_SEEK_BASE_COST=0.9. - - If handler::avg_io_cost() < 1.0, then we will trust the handler - when it comes to the average cost (this is for example true for HEAP). - @param table Table to be accessed @param nrows Number of rows to retrieve @param interrupted TRUE <=> Assume that the disk sweep will be @@ -2087,16 +2121,18 @@ void get_sort_and_sweep_cost(TABLE *table, ha_rows nrows, Cost_estimate *cost) @param cost OUT The cost. */ -void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, - Cost_estimate *cost) +static void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, + Cost_estimate *cost) { DBUG_ENTER("get_sweep_read_cost"); - cost->reset(); +#ifndef OLD_SWEEP_COST + cost->row_cost= table->file->ha_rnd_pos_call_time(nrows); +#else if (table->file->pk_is_clustering_key(table->s->primary_key)) { - cost->cpu_cost= table->file->read_time(table->s->primary_key, - (uint) nrows, nrows); + cost->cpu_cost= table->file->ha_read_and_copy_time(table->s->primary_key, + (uint) nrows, nrows); } else if ((cost->avg_io_cost= table->file->avg_io_cost()) >= 0.999) { @@ -2118,7 +2154,9 @@ void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, DISK_SEEK_PROP_COST*n_blocks/busy_blocks); } } - DBUG_PRINT("info",("returning cost=%g", cost->total_cost())); + cost->cpu_cost+= rows2double(n_rows) * ROW_COPY_COST; +#endif + DBUG_PRINT("info",("returning cost: %g", cost->total_cost())); DBUG_VOID_RETURN; } diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h index 37a00e3086f..76b026f994a 100644 --- a/sql/multi_range_read.h +++ b/sql/multi_range_read.h @@ -576,7 +576,7 @@ public: ha_rows dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost); + uint *flags, ha_rows limit, Cost_estimate *cost); int dsmrr_explain_info(uint mrr_mode, char *str, size_t size); private: diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index 7840476b878..b16c7146a28 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -405,7 +405,7 @@ public: #endif } - bool trace_started() const + inline bool trace_started() const { return my_writer != 0; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d7543d86ec1..ff69af07f6e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -52,6 +52,7 @@ #include "sql_expression_cache.h" // subquery_cache_miss, subquery_cache_hit #include "sys_vars_shared.h" #include "ddl_log.h" +#include "optimizer_defaults.h" #include #include @@ -733,7 +734,7 @@ mysql_mutex_t LOCK_prepared_stmt_count; #ifdef HAVE_OPENSSL mysql_mutex_t LOCK_des_key_file; #endif -mysql_mutex_t LOCK_backup_log; +mysql_mutex_t LOCK_backup_log, LOCK_optimizer_costs; mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; mysql_rwlock_t LOCK_ssl_refresh; mysql_rwlock_t LOCK_all_status_vars; @@ -756,8 +757,6 @@ char *opt_relay_logname = 0, *opt_relaylog_index_name=0; char *opt_logname, *opt_slow_logname, *opt_bin_logname; char *opt_binlog_index_name=0; - - /* Static variables */ my_bool opt_stack_trace; @@ -905,7 +904,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_LOCK_crypt, key_LOCK_delayed_create, key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log, key_LOCK_gdl, key_LOCK_global_system_variables, - key_LOCK_manager, key_LOCK_backup_log, + key_LOCK_manager, key_LOCK_backup_log, key_LOCK_optimizer_costs, key_LOCK_prepared_stmt_count, key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status, key_LOCK_temp_pool, @@ -968,6 +967,7 @@ static PSI_mutex_info all_server_mutexes[]= { &key_hash_filo_lock, "hash_filo::lock", 0}, { &key_LOCK_active_mi, "LOCK_active_mi", PSI_FLAG_GLOBAL}, { &key_LOCK_backup_log, "LOCK_backup_log", PSI_FLAG_GLOBAL}, + { &key_LOCK_optimizer_costs, "LOCK_optimizer_costs", PSI_FLAG_GLOBAL}, { &key_LOCK_temp_pool, "LOCK_temp_pool", PSI_FLAG_GLOBAL}, { &key_LOCK_thread_id, "LOCK_thread_id", PSI_FLAG_GLOBAL}, { &key_LOCK_crypt, "LOCK_crypt", PSI_FLAG_GLOBAL}, @@ -2008,6 +2008,7 @@ static void clean_up(bool print_message) mdl_destroy(); dflt_key_cache= 0; key_caches.delete_elements(free_key_cache); + free_all_optimizer_costs(); wt_end(); multi_keycache_free(); sp_cache_end(); @@ -2130,6 +2131,7 @@ static void clean_up_mutexes() mysql_mutex_destroy(&LOCK_active_mi); mysql_rwlock_destroy(&LOCK_ssl_refresh); mysql_mutex_destroy(&LOCK_backup_log); + mysql_mutex_destroy(&LOCK_optimizer_costs); mysql_mutex_destroy(&LOCK_temp_pool); mysql_rwlock_destroy(&LOCK_sys_init_connect); mysql_rwlock_destroy(&LOCK_sys_init_slave); @@ -4443,7 +4445,6 @@ static int init_common_variables() return 1; } - #ifdef WITH_WSREP /* We need to initialize auxiliary variables, that will be @@ -4505,6 +4506,8 @@ static int init_thread_environment() mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered, MY_MUTEX_INIT_SLOW); mysql_mutex_init(key_LOCK_backup_log, &LOCK_backup_log, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_optimizer_costs, &LOCK_optimizer_costs, + MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_temp_pool, &LOCK_temp_pool, MY_MUTEX_INIT_FAST); #ifdef HAVE_OPENSSL @@ -4860,6 +4863,25 @@ init_gtid_pos_auto_engines(void) return 0; } + +#define us_to_ms(X) if (X > 0) X/= 1000; +static int adjust_optimizer_costs(void *, OPTIMIZER_COSTS *oc, void *) +{ + us_to_ms(oc->disk_read_cost); + us_to_ms(oc->index_block_copy_cost); + us_to_ms(oc->key_cmp_cost); + us_to_ms(oc->key_copy_cost); + us_to_ms(oc->key_lookup_cost); + us_to_ms(oc->key_next_find_cost); + us_to_ms(oc->row_copy_cost); + us_to_ms(oc->row_lookup_cost); + us_to_ms(oc->row_next_find_cost); + us_to_ms(oc->rowid_cmp_cost); + us_to_ms(oc->rowid_copy_cost); + return 0; +} + + #define MYSQL_COMPATIBILITY_OPTION(option) \ { option, OPT_MYSQL_COMPATIBILITY, \ 0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 } @@ -5001,12 +5023,12 @@ static int init_server_components() /* need to configure logging before initializing storage engines */ if (!opt_bin_log_used && !WSREP_ON) { - if (opt_log_slave_updates) - sql_print_warning("You need to use --log-bin to make " - "--log-slave-updates work."); - if (binlog_format_used) - sql_print_warning("You need to use --log-bin to make " - "--binlog-format work."); + if (opt_log_slave_updates && (global_system_variables.log_warnings >= 4)) + sql_print_information("You need to use --log-bin to make " + "--log-slave-updates work."); + if (binlog_format_used && (global_system_variables.log_warnings >= 4)) + sql_print_information("You need to use --log-bin to make " + "--binlog-format work."); } /* Check that we have not let the format to unspecified at this point */ @@ -5204,8 +5226,15 @@ static int init_server_components() tc_log= 0; // ha_initialize_handlerton() needs that - if (!opt_abort && ddl_log_initialize()) - unireg_abort(1); + if (!opt_abort) + { + if (ddl_log_initialize()) + unireg_abort(1); + + process_optimizer_costs((process_optimizer_costs_t)adjust_optimizer_costs, 0); + us_to_ms(global_system_variables.optimizer_where_cost); + us_to_ms(global_system_variables.optimizer_scan_setup_cost); + } if (plugin_init(&remaining_argc, remaining_argv, (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) | @@ -5435,6 +5464,7 @@ static int init_server_components() unireg_abort(1); } #endif + copy_tmptable_optimizer_costs(); #ifdef WITH_WSREP /* @@ -5493,9 +5523,9 @@ static int init_server_components() } else { - if (binlog_expire_logs_seconds) - sql_print_warning("You need to use --log-bin to make --expire-logs-days " - "or --binlog-expire-logs-seconds work."); + if (binlog_expire_logs_seconds && (global_system_variables.log_warnings >= 4)) + sql_print_information("You need to use --log-bin to make --expire-logs-days " + "or --binlog-expire-logs-seconds work."); } #endif @@ -7408,12 +7438,14 @@ SHOW_VAR status_vars[]= { {"Feature_dynamic_columns", (char*) offsetof(STATUS_VAR, feature_dynamic_columns), SHOW_LONG_STATUS}, {"Feature_fulltext", (char*) offsetof(STATUS_VAR, feature_fulltext), SHOW_LONG_STATUS}, {"Feature_gis", (char*) offsetof(STATUS_VAR, feature_gis), SHOW_LONG_STATUS}, - {"Feature_insert_returning", (char*)offsetof(STATUS_VAR, feature_insert_returning), SHOW_LONG_STATUS}, - {"Feature_invisible_columns", (char*) offsetof(STATUS_VAR, feature_invisible_columns), SHOW_LONG_STATUS}, + {"Feature_insert_returning", (char*)offsetof(STATUS_VAR, feature_insert_returning), SHOW_LONG_STATUS}, + {"Feature_into_outfile", (char*) offsetof(STATUS_VAR, feature_into_outfile), SHOW_LONG_STATUS}, + {"Feature_into_variable", (char*) offsetof(STATUS_VAR, feature_into_variable), SHOW_LONG_STATUS}, + {"Feature_invisible_columns",(char*) offsetof(STATUS_VAR, feature_invisible_columns), SHOW_LONG_STATUS}, {"Feature_json", (char*) offsetof(STATUS_VAR, feature_json), SHOW_LONG_STATUS}, {"Feature_locale", (char*) offsetof(STATUS_VAR, feature_locale), SHOW_LONG_STATUS}, {"Feature_subquery", (char*) offsetof(STATUS_VAR, feature_subquery), SHOW_LONG_STATUS}, - {"Feature_system_versioning", (char*) offsetof(STATUS_VAR, feature_system_versioning), SHOW_LONG_STATUS}, + {"Feature_system_versioning",(char*) offsetof(STATUS_VAR, feature_system_versioning), SHOW_LONG_STATUS}, {"Feature_application_time_periods", (char*) offsetof(STATUS_VAR, feature_application_time_periods), SHOW_LONG_STATUS}, {"Feature_timezone", (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS}, {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS}, @@ -7828,12 +7860,17 @@ static int mysql_init_variables(void) strnmov(server_version, MYSQL_SERVER_VERSION, sizeof(server_version)-1); thread_cache.init(); key_caches.empty(); - if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str, - default_key_cache_base.length))) + if (!(dflt_key_cache= get_or_create_key_cache(default_base.str, + default_base.length))) { sql_print_error("Cannot allocate the keycache"); return 1; } + if (create_default_optimizer_costs()) + { + sql_print_error("Cannot allocate optimizer_costs"); + return 1; + } /* set key_cache_hash.default_value = dflt_key_cache */ multi_keycache_init(); @@ -8407,11 +8444,14 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument, } -/** Handle arguments for multiple key caches. */ +/** + Handle arguments for multiple key caches, replication_options and + optimizer_costs + */ C_MODE_START -static void* +static void * mysql_getopt_value(const char *name, uint length, const struct my_option *option, int *error) { @@ -8449,6 +8489,7 @@ mysql_getopt_value(const char *name, uint length, } /* We return in all cases above. Let us silence -Wimplicit-fallthrough */ DBUG_ASSERT(0); + break; #ifdef HAVE_REPLICATION /* fall through */ case OPT_REPLICATE_DO_DB: @@ -8476,11 +8517,62 @@ mysql_getopt_value(const char *name, uint length, } return 0; } + break; #endif + case OPT_COSTS_DISK_READ_COST: + case OPT_COSTS_INDEX_BLOCK_COPY_COST: + case OPT_COSTS_KEY_CMP_COST: + case OPT_COSTS_KEY_COPY_COST: + case OPT_COSTS_KEY_LOOKUP_COST: + case OPT_COSTS_KEY_NEXT_FIND_COST: + case OPT_COSTS_DISK_READ_RATIO: + case OPT_COSTS_ROW_COPY_COST: + case OPT_COSTS_ROW_LOOKUP_COST: + case OPT_COSTS_ROW_NEXT_FIND_COST: + case OPT_COSTS_ROWID_CMP_COST: + case OPT_COSTS_ROWID_COPY_COST: + { + OPTIMIZER_COSTS *costs; + if (unlikely(!(costs= get_or_create_optimizer_costs(name, length)))) + { + if (error) + *error= EXIT_OUT_OF_MEMORY; + return 0; + } + switch (option->id) { + case OPT_COSTS_DISK_READ_COST: + return &costs->disk_read_cost; + case OPT_COSTS_INDEX_BLOCK_COPY_COST: + return &costs->index_block_copy_cost; + case OPT_COSTS_KEY_CMP_COST: + return &costs->key_cmp_cost; + case OPT_COSTS_KEY_COPY_COST: + return &costs->key_copy_cost; + case OPT_COSTS_KEY_LOOKUP_COST: + return &costs->key_lookup_cost; + case OPT_COSTS_KEY_NEXT_FIND_COST: + return &costs->key_next_find_cost; + case OPT_COSTS_DISK_READ_RATIO: + return &costs->disk_read_ratio; + case OPT_COSTS_ROW_COPY_COST: + return &costs->row_copy_cost; + case OPT_COSTS_ROW_LOOKUP_COST: + return &costs->row_lookup_cost; + case OPT_COSTS_ROW_NEXT_FIND_COST: + return &costs->row_next_find_cost; + case OPT_COSTS_ROWID_CMP_COST: + return &costs->rowid_cmp_cost; + case OPT_COSTS_ROWID_COPY_COST: + return &costs->rowid_copy_cost; + default: + DBUG_ASSERT(0); + } + } } return option->value; } + static void option_error_reporter(enum loglevel level, const char *format, ...) { va_list args; @@ -9084,7 +9176,7 @@ void refresh_status(THD *thd) reset_pfs_status_stats(); #endif - /* Add thread's status variabes to global status */ + /* Add thread's status variabels to global status */ add_to_status(&global_status_var, &thd->status_var); /* Reset thread's status variables */ diff --git a/sql/mysqld.h b/sql/mysqld.h index 449c2e50a58..54cafdcde15 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -330,7 +330,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_LOCK_logger, key_LOCK_manager, key_LOCK_prepared_stmt_count, key_LOCK_rpl_status, key_LOCK_server_started, - key_LOCK_status, + key_LOCK_status, key_LOCK_optimizer_costs, key_LOCK_thd_data, key_LOCK_thd_kill, key_LOCK_user_conn, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, @@ -759,7 +759,8 @@ extern mysql_mutex_t LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_active_mi, LOCK_manager, LOCK_user_conn, - LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_backup_log; + LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_backup_log, + LOCK_optimizer_costs; extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_global_system_variables; extern mysql_rwlock_t LOCK_all_status_vars; extern mysql_mutex_t LOCK_start_thread; @@ -794,6 +795,18 @@ enum options_mysqld OPT_BINLOG_IGNORE_DB, OPT_BIN_LOG, OPT_BOOTSTRAP, + OPT_COSTS_DISK_READ_COST, + OPT_COSTS_INDEX_BLOCK_COPY_COST, + OPT_COSTS_KEY_CMP_COST, + OPT_COSTS_KEY_COPY_COST, + OPT_COSTS_KEY_LOOKUP_COST, + OPT_COSTS_KEY_NEXT_FIND_COST, + OPT_COSTS_DISK_READ_RATIO, + OPT_COSTS_ROW_COPY_COST, + OPT_COSTS_ROW_LOOKUP_COST, + OPT_COSTS_ROW_NEXT_FIND_COST, + OPT_COSTS_ROWID_CMP_COST, + OPT_COSTS_ROWID_COPY_COST, OPT_EXPIRE_LOGS_DAYS, OPT_BINLOG_EXPIRE_LOGS_SECONDS, OPT_CONSOLE, diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc index 6a24fa95b68..51aa70fa02c 100644 --- a/sql/opt_index_cond_pushdown.cc +++ b/sql/opt_index_cond_pushdown.cc @@ -17,6 +17,7 @@ #include "mariadb.h" #include "sql_select.h" #include "sql_test.h" +#include "opt_trace.h" /**************************************************************************** * Index Condition Pushdown code starts @@ -334,13 +335,12 @@ void push_index_cond(JOIN_TAB *tab, uint keyno) than on a non-clustered key. This restriction should be re-evaluated when WL#6061 is implemented. */ - if ((tab->table->file->index_flags(keyno, 0, 1) & - HA_DO_INDEX_COND_PUSHDOWN) && + if ((tab->table->key_info[keyno].index_flags & HA_DO_INDEX_COND_PUSHDOWN) && optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN) && tab->join->thd->lex->sql_command != SQLCOM_UPDATE_MULTI && tab->join->thd->lex->sql_command != SQLCOM_DELETE_MULTI && tab->type != JT_CONST && tab->type != JT_SYSTEM && - !tab->table->file->is_clustering_key(keyno)) // 6 + !tab->table->is_clustering_key(keyno)) // 6 { DBUG_EXECUTE("where", print_where(tab->select_cond, "full cond", QT_ORDINARY);); @@ -355,6 +355,8 @@ void push_index_cond(JOIN_TAB *tab, uint keyno) { Item *idx_remainder_cond= 0; tab->pre_idx_push_select_cond= tab->select_cond; + Json_writer_object trace(tab->join->thd); + trace.add_table_name(tab); /* For BKA cache we store condition to special BKA cache field because evaluation of the condition requires additional operations @@ -387,6 +389,7 @@ void push_index_cond(JOIN_TAB *tab, uint keyno) idx_remainder_cond= NULL; } } + trace.add("index_condition", idx_cond); /* Disable eq_ref's "lookup cache" if we've pushed down an index @@ -424,6 +427,10 @@ void push_index_cond(JOIN_TAB *tab, uint keyno) } else tab->select_cond= idx_remainder_cond; + + if (tab->select_cond) + trace.add("row_condition", tab->select_cond); + if (tab->select) { DBUG_EXECUTE("where", diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 05443ea78bf..f2696683124 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -19,8 +19,8 @@ Fix that MAYBE_KEY are stored in the tree so that we can detect use of full hash keys for queries like: - select s.id, kws.keyword_id from sites as s,kws where s.id=kws.site_id and kws.keyword_id in (204,205); - + select s.id, kws.keyword_id from sites as s,kws where s.id=kws.site_id and + kws.keyword_id in (204,205); */ /* @@ -345,7 +345,8 @@ struct st_index_scan_info; struct st_ror_scan_info; static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts); -static ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, +static ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit, + bool index_only, SEL_ARG *tree, bool update_tbl_stats, uint *mrr_flags, uint *bufsize, Cost_estimate *cost, bool *is_ror_scan); @@ -356,7 +357,8 @@ QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index, static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, bool index_read_must_be_used, bool for_range_access, - double read_time); + double read_time, ha_rows limit, + bool using_table_scan); static TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, double read_time); @@ -370,7 +372,9 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, double read_time); static TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, - double read_time, bool named_trace= false); + double read_time, ha_rows limit, + bool named_trace, + bool using_table_scan); static TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, TRP_INDEX_MERGE *imerge_trp, @@ -412,7 +416,6 @@ static bool eq_tree(SEL_ARG* a,SEL_ARG *b); SEL_ARG null_element(SEL_ARG::IMPOSSIBLE); static bool null_part_in_key(KEY_PART *key_part, const uchar *key, uint length); -static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts); static SEL_ARG *enforce_sel_arg_weight_limit(RANGE_OPT_PARAM *param, uint keyno, @@ -2171,6 +2174,27 @@ int SEL_ARG::sel_cmp(Field *field, uchar *a, uchar *b, uint8 a_flag, } +/* + Check if min and values are equal + + @return 1 if equal +*/ + +bool SEL_ARG::min_max_are_equal() const +{ + uint offset= 0; + if (field->real_maybe_null()) // If null is part of key + { + if (*min_value != *max_value) + return 0; + if (*min_value) + return 1; // NULL where equal + offset= 1; // Skip NULL marker + } + return field->key_cmp(min_value+offset, max_value+offset) == 0; +} + + SEL_ARG *SEL_ARG::clone_tree(RANGE_OPT_PARAM *param) { SEL_ARG tmp_link,*next_arg,*root; @@ -2294,9 +2318,11 @@ void TRP_RANGE::trace_basic_info(PARAM *param, const KEY &cur_key= param->table->key_info[keynr_in_table]; const KEY_PART_INFO *key_part= cur_key.key_part; - trace_object->add("type", "range_scan") - .add("index", cur_key.name) - .add("rows", records); + if (unlikely(trace_object->trace_started())) + trace_object-> + add("type", "range_scan"). + add("index", cur_key.name). + add("rows", records); Json_writer_array trace_range(param->thd, "ranges"); @@ -2323,6 +2349,7 @@ public: struct st_ror_scan_info *cpk_scan; /* Clustered PK scan, if there is one */ bool is_covering; /* TRUE if no row retrieval phase is necessary */ double index_scan_costs; /* SUM(cost(index_scan)) */ + double cmp_cost; // Cost of out rows with WHERE clause void trace_basic_info(PARAM *param, Json_writer_object *trace_object) const; }; @@ -2439,20 +2466,21 @@ void TRP_INDEX_MERGE::trace_basic_info(PARAM *param, class TRP_GROUP_MIN_MAX : public TABLE_READ_PLAN { private: - bool have_min, have_max, have_agg_distinct; - KEY_PART_INFO *min_max_arg_part; uint group_prefix_len; uint used_key_parts; uint group_key_parts; - KEY *index_info; uint index; uint key_infix_len; + uint param_idx; /* Index of used key in param->key. */ uchar key_infix[MAX_KEY_LENGTH]; + KEY *index_info; + KEY_PART_INFO *min_max_arg_part; SEL_TREE *range_tree; /* Represents all range predicates in the query. */ SEL_ARG *index_tree; /* The SEL_ARG sub-tree corresponding to index_info. */ - uint param_idx; /* Index of used key in param->key. */ - bool is_index_scan; /* Use index_next() instead of random read */ + bool have_min, have_max; public: + bool have_agg_distinct; + bool is_index_scan; /* Use index_next() instead of random read */ /* Number of records selected by the ranges in index_tree. */ ha_rows quick_prefix_records; public: @@ -2465,13 +2493,14 @@ public: uchar *key_infix_arg, SEL_TREE *tree_arg, SEL_ARG *index_tree_arg, uint param_idx_arg, ha_rows quick_prefix_records_arg) - : have_min(have_min_arg), have_max(have_max_arg), + : group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg), + group_key_parts(group_key_parts_arg), + index(index_arg), key_infix_len(key_infix_len_arg), param_idx(param_idx_arg), + index_info(index_info_arg),min_max_arg_part(min_max_arg_part_arg), + range_tree(tree_arg), index_tree(index_tree_arg), + have_min(have_min_arg), have_max(have_max_arg), have_agg_distinct(have_agg_distinct_arg), - min_max_arg_part(min_max_arg_part_arg), - group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg), - group_key_parts(group_key_parts_arg), index_info(index_info_arg), - index(index_arg), key_infix_len(key_infix_len_arg), range_tree(tree_arg), - index_tree(index_tree_arg), param_idx(param_idx_arg), is_index_scan(FALSE), + is_index_scan(FALSE), quick_prefix_records(quick_prefix_records_arg) { if (key_infix_len) @@ -2500,11 +2529,13 @@ void TRP_GROUP_MIN_MAX::trace_basic_info(PARAM *param, else trace_object->add_null("min_max_arg"); - trace_object->add("min_aggregate", have_min) - .add("max_aggregate", have_max) - .add("distinct_aggregate", have_agg_distinct) - .add("rows", records) - .add("cost", read_cost); + if (unlikely(trace_object->trace_started())) + trace_object-> + add("min_aggregate", have_min). + add("max_aggregate", have_max). + add("distinct_aggregate", have_agg_distinct). + add("rows", records). + add("cost", read_cost); const KEY_PART_INFO *key_part= index_info->key_part; { @@ -2626,7 +2657,8 @@ static int fill_used_fields_bitmap(PARAM *param) In the table struct the following information is updated: quick_keys - Which keys can be used quick_rows - How many rows the key matches - opt_range_condition_rows - E(# rows that will satisfy the table condition) + opt_range_condition_rows - E(# rows that will satisfy the table + condition) IMPLEMENTATION opt_range_condition_rows value is obtained as follows: @@ -2679,15 +2711,19 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, bool only_single_index_range_scan) { uint idx; - double scan_time; Item *notnull_cond= NULL; TABLE_READ_PLAN *best_trp= NULL; SEL_ARG **backup_keys= 0; + ha_rows table_records= head->stat_records(); + handler *file= head->file; + bool impossible_range= 0; DBUG_ENTER("SQL_SELECT::test_quick_select"); DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu", (ulong) keys_to_use.to_ulonglong(), (ulong) prev_tables, (ulong) const_tables)); - DBUG_PRINT("info", ("records: %lu", (ulong) head->stat_records())); + DBUG_PRINT("info", ("records: %llu", (ulonglong) table_records)); + DBUG_ASSERT(table_records || !head->file->stats.records); + delete quick; quick=0; needed_reg.clear_all(); @@ -2696,40 +2732,29 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, DBUG_ASSERT(!head->is_filled_at_execution()); if (keys_to_use.is_clear_all() || head->is_filled_at_execution()) DBUG_RETURN(0); - records= head->stat_records(); + records= table_records; notnull_cond= head->notnull_cond; - if (!records) - records++; /* purecov: inspected */ - if (head->file->ha_table_flags() & HA_NON_COMPARABLE_ROWID) + if (file->ha_table_flags() & HA_NON_COMPARABLE_ROWID) only_single_index_range_scan= 1; if (head->force_index || force_quick_range) - scan_time= read_time= DBL_MAX; + read_time= DBL_MAX; else { - scan_time= rows2double(records) / TIME_FOR_COMPARE; - /* - The 2 is there to prefer range scans to full table scans. - This is mainly to make the test suite happy as many tests has - very few rows. In real life tables has more than a few rows and the - +2 has no practical effect. - */ - read_time= (double) head->file->scan_time() + scan_time + 2; - if (limit < records && read_time < (double) records + scan_time + 1 ) - { - read_time= (double) records + scan_time + 1; // Force to use index + read_time= file->cost(file->ha_scan_and_compare_time(records)); + if (limit < records) notnull_cond= NULL; - } } possible_keys.clear_all(); DBUG_PRINT("info",("Time to scan table: %g", read_time)); - Json_writer_object table_records(thd); - table_records.add_table_name(head); + Json_writer_object table_info(thd); + table_info.add_table_name(head); Json_writer_object trace_range(thd, "range_analysis"); + if (unlikely(thd->trace_started()) && read_time != DBL_MAX) { Json_writer_object table_rec(thd, "table_scan"); table_rec.add("rows", records).add("cost", read_time); @@ -2745,14 +2770,14 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, KEY_PART *key_parts; KEY *key_info; PARAM param; - bool force_group_by = false; + bool force_group_by= false, group_by_optimization_used= false; if (check_stack_overrun(thd, 2*STACK_MIN_SIZE + sizeof(PARAM), buff)) DBUG_RETURN(0); // Fatal error flag is set /* set up parameter that is passed to all functions */ param.thd= thd; - param.baseflag= head->file->ha_table_flags(); + param.baseflag= file->ha_table_flags(); param.prev_tables=prev_tables | const_tables; param.read_tables=read_tables; param.current_table= head->map; @@ -2771,7 +2796,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, thd->no_errors=1; // Don't warn about NULL init_sql_alloc(key_memory_quick_range_select_root, &alloc, - thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); + thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc, sizeof(KEY_PART) * @@ -2802,8 +2828,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if (!keys_to_use.is_set(idx)) { - trace_idx_details.add("usable", false) - .add("cause", "not applicable"); + if (unlikely(trace_idx_details.trace_started())) + trace_idx_details. + add("usable", false). + add("cause", "not applicable"); continue; } if (key_info->flags & HA_FULLTEXT) @@ -2853,11 +2881,14 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, thd->mem_root= &alloc; /* Calculate cost of full index read for the shortest covering index */ - if (!force_quick_range && !head->covering_keys.is_clear_all()) + if (!force_quick_range && !head->covering_keys.is_clear_all() && + !head->no_keyread) { - int key_for_use= find_shortest_key(head, &head->covering_keys); - double key_read_time= (head->file->key_scan_time(key_for_use) + - rows2double(records) / TIME_FOR_COMPARE); + double key_read_time; + uint key_for_use= find_shortest_key(head, &head->covering_keys); + key_read_time= file->cost(file-> + ha_key_scan_and_compare_time(key_for_use, + records)); DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, " "read time %g", key_for_use, key_read_time)); @@ -2868,10 +2899,14 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, read_time= key_read_time; chosen= TRUE; } - trace_cov.add("index", head->key_info[key_for_use].name) - .add("cost", key_read_time).add("chosen", chosen); - if (!chosen) - trace_cov.add("cause", "cost"); + if (unlikely(trace_cov.trace_started())) + { + trace_cov. + add("index", head->key_info[key_for_use].name). + add("cost", key_read_time).add("chosen", chosen); + if (!chosen) + trace_cov.add("cause", "cost"); + } } double best_read_time= read_time; @@ -2893,7 +2928,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, { if (tree->type == SEL_TREE::IMPOSSIBLE) { - records=0L; /* Return -1 from this function. */ + records= 0; + impossible_range= 1; /* Return -1 from this function. */ read_time= (double) HA_POS_ERROR; trace_range.add("impossible_range", true); goto free_mem; @@ -2927,6 +2963,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, TRP_INDEX_INTERSECT *intersect_trp; bool can_build_covering= FALSE; Json_writer_object trace_range(thd, "analyzing_range_alternatives"); + TABLE_READ_PLAN *range_trp; backup_keys= (SEL_ARG**) alloca(sizeof(backup_keys[0])*param.keys); memcpy(&backup_keys[0], &tree->keys[0], @@ -2935,9 +2972,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, remove_nonrange_trees(¶m, tree); /* Get best 'range' plan and prepare data for making other plans */ - if (auto range_trp= get_key_scans_params(¶m, tree, - only_single_index_range_scan, - true, best_read_time)) + if ((range_trp= get_key_scans_params(¶m, tree, + only_single_index_range_scan, + true, best_read_time, limit, + 1))) { best_trp= range_trp; best_read_time= best_trp->read_cost; @@ -2959,8 +2997,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if ((rori_trp= get_best_ror_intersect(¶m, tree, best_read_time, &can_build_covering))) { - best_trp= rori_trp; - best_read_time= best_trp->read_cost; + best_trp= rori_trp; + best_read_time= rori_trp->read_cost; /* Try constructing covering ROR-intersect only if it looks possible and worth doing. @@ -2984,15 +3022,14 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if ((intersect_trp= get_best_index_intersect(¶m, tree, best_read_time))) { - best_trp= intersect_trp; - best_read_time= best_trp->read_cost; - set_if_smaller(param.table->opt_range_condition_rows, - intersect_trp->records); + best_trp= intersect_trp; + best_read_time= intersect_trp->read_cost; + param.table->set_opt_range_condition_rows(intersect_trp->records); } } if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) && - head->stat_records() != 0 && !only_single_index_range_scan) + table_records != 0 && !only_single_index_range_scan) { /* Try creating index_merge/ROR-union scan. */ SEL_IMERGE *imerge; @@ -3004,10 +3041,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, Json_writer_array trace_idx_merge(thd, "analyzing_index_merge_union"); while ((imerge= it++)) { - new_conj_trp= get_best_disjunct_quick(¶m, imerge, best_read_time); + new_conj_trp= get_best_disjunct_quick(¶m, imerge, best_read_time, + limit, 0, 1); if (new_conj_trp) - set_if_smaller(param.table->opt_range_condition_rows, - new_conj_trp->records); + param.table->set_opt_range_condition_rows(new_conj_trp->records); if (new_conj_trp && (!best_conj_trp || new_conj_trp->read_cost < best_conj_trp->read_cost)) @@ -3029,22 +3066,51 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if (!only_single_index_range_scan) { TRP_GROUP_MIN_MAX *group_trp; + double duplicate_removal_cost= 0; if (tree) restore_nonrange_trees(¶m, tree, backup_keys); if ((group_trp= get_best_group_min_max(¶m, tree, read_time))) { - param.table->opt_range_condition_rows= MY_MIN(group_trp->records, - head->stat_records()); + /* mark that we are changing opt_range_condition_rows */ + group_by_optimization_used= 1; + param.table->set_opt_range_condition_rows(group_trp->records); + DBUG_PRINT("info", ("table_rows: %llu opt_range_condition_rows: %llu " + "group_trp->records: %ull", + table_records, + param.table->opt_range_condition_rows, + group_trp->records)); + Json_writer_object grp_summary(thd, "best_group_range_summary"); if (unlikely(thd->trace_started())) group_trp->trace_basic_info(¶m, &grp_summary); - if (group_trp->read_cost < best_read_time || force_group_by) + if (group_trp->have_agg_distinct && group_trp->is_index_scan) { - grp_summary.add("chosen", true); + /* + We are optimization a distinct aggregate, like + SELECT count(DISTINCT a,b,c) FROM ... + + The group cost includes removal of the distinct, so to be + able to compare costs, we add small cost to the original cost + that stands for the extra work we have to do on the outside of + the engine to do duplicate elimination for each output row if + we are not using the grouping code. + */ + duplicate_removal_cost= (DUPLICATE_REMOVAL_COST * + (best_trp ? best_trp->records : + table_records)); + } + if (group_trp->read_cost < best_read_time + duplicate_removal_cost || + force_group_by) + { + if (thd->trace_started()) + { + if (duplicate_removal_cost) + grp_summary.add("duplicate_removal_cost", duplicate_removal_cost); + grp_summary.add("chosen", true); + } best_trp= group_trp; - best_read_time= best_trp->read_cost; } else grp_summary.add("chosen", false).add("cause", "cost"); @@ -3059,11 +3125,14 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if (best_trp) { records= best_trp->records; + impossible_range= records == 0; // No matching rows if (!(quick= best_trp->make_quick(¶m, TRUE)) || quick->init()) { delete quick; quick= NULL; } + else + quick->group_by_optimization_used= group_by_optimization_used; } possible_keys= param.possible_keys; @@ -3076,9 +3145,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, Json_writer_object trace_range_plan(thd, "range_access_plan"); best_trp->trace_basic_info(¶m, &trace_range_plan); } - trace_range_summary.add("rows_for_plan", quick->records) - .add("cost_for_plan", quick->read_time) - .add("chosen", true); + trace_range_summary. + add("rows_for_plan", quick->records). + add("cost_for_plan", quick->read_time). + add("chosen", true); } free_root(&alloc,MYF(0)); // Return memory & allocator @@ -3092,7 +3162,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, Assume that if the user is using 'limit' we will only need to scan limit rows if we are using a key */ - DBUG_RETURN(records ? MY_TEST(quick) : -1); + set_if_smaller(records, table_records); + DBUG_RETURN(impossible_range ? -1 : MY_TEST(quick)); } /**************************************************************************** @@ -3106,7 +3177,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, SYNOPSIS create_key_parts_for_pseudo_indexes() param IN/OUT data structure for the descriptors to be built - used_fields bitmap of columns for which the descriptors are to be built + used_fields bitmap of columns for which the descriptors are to be built DESCRIPTION For each column marked in the bitmap used_fields the function builds @@ -3203,9 +3274,10 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param, SYNOPSIS records_in_column_ranges() param the data structure to access descriptors of pseudo indexes - built over columns used in the condition of the processed query + built over columns used in the condition of the processed + query idx the index of the descriptor of interest in param - tree the tree representing ranges built for the interesting column + tree the tree representing ranges built for the interesting column DESCRIPTION This function retrieves the ranges represented by the SEL_ARG 'tree' and @@ -3229,7 +3301,7 @@ double records_in_column_ranges(PARAM *param, uint idx, SEL_ARG_RANGE_SEQ seq; KEY_MULTI_RANGE range; range_seq_t seq_it; - double rows; + double rows, table_records; Field *field; uint flags= 0; double total_rows= 0; @@ -3284,13 +3356,17 @@ double records_in_column_ranges(PARAM *param, uint idx, total_rows= DBL_MAX; break; } - total_rows += rows; + total_rows+= rows; } if (total_rows == 0) total_rows= MY_MIN(1, rows2double(param->table->stat_records())); - return total_rows; -} + table_records= rows2double(param->table->stat_records()); + if (total_rows > table_records) + DBUG_PRINT("error", ("table_records: %g < total_records: %g", + table_records, total_rows)); + return MY_MIN(total_rows, table_records); +} /* @@ -3303,12 +3379,12 @@ double records_in_column_ranges(PARAM *param, uint idx, */ static -int cmp_quick_ranges(TABLE *table, uint *a, uint *b) +int cmp_quick_ranges(TABLE::OPT_RANGE **a, TABLE::OPT_RANGE **b) { - int tmp= CMP_NUM(table->opt_range[*a].rows, table->opt_range[*b].rows); + int tmp=CMP_NUM((*a)->rows, (*b)->rows); if (tmp) return tmp; - return -CMP_NUM(table->opt_range[*a].key_parts, table->opt_range[*b].key_parts); + return -CMP_NUM((*a)->key_parts, (*b)->key_parts); } @@ -3324,7 +3400,8 @@ int cmp_quick_ranges(TABLE *table, uint *a, uint *b) DESCRIPTION This function calculates the selectivity of range conditions cond imposed on the rows of 'table' in the processed query. - The calculated selectivity is assigned to the field table->cond_selectivity. + The calculated selectivity is assigned to the field + table->cond_selectivity. Selectivity is calculated as a product of selectivities imposed by: @@ -3336,6 +3413,8 @@ int cmp_quick_ranges(TABLE *table, uint *a, uint *b) 3. Reading a few records from the table pages and checking the condition selectivity (this is used for conditions like "column LIKE '%val%'" where approaches #1 and #2 do not provide selectivity data). + 4. If the selectivity calculated by get_best_ror_intersect() is smaller, + use this instead. NOTE Currently the selectivities of range conditions over different columns are @@ -3350,31 +3429,40 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) { uint keynr, range_index, ranges; MY_BITMAP *used_fields= &table->cond_set; - double table_records= (double)table->stat_records(); - uint optimal_key_order[MAX_KEY]; + double table_records= (double)table->stat_records(), original_selectivity; + TABLE::OPT_RANGE *optimal_key_order[MAX_KEY]; + MY_BITMAP handled_columns; + my_bitmap_map *buf; + QUICK_SELECT_I *quick; DBUG_ENTER("calculate_cond_selectivity_for_table"); - table->cond_selectivity= 1.0; + table->set_cond_selectivity(1.0); if (table_records == 0) DBUG_RETURN(FALSE); - QUICK_SELECT_I *quick; if ((quick=table->reginfo.join_tab->quick) && quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) { - table->cond_selectivity*= (quick->records/table_records); + DBUG_ASSERT(table->opt_range_condition_rows <= quick->records); + table->set_cond_selectivity(MY_MIN(quick->records, + table->opt_range_condition_rows)/ + table_records); DBUG_RETURN(FALSE); } - if (!*cond) + if (!*cond || table->pos_in_table_list->schema_table) + { + table->set_cond_selectivity(table->opt_range_condition_rows / + table_records); DBUG_RETURN(FALSE); + } - if (table->pos_in_table_list->schema_table) - DBUG_RETURN(FALSE); - - MY_BITMAP handled_columns; - my_bitmap_map* buf; + /* + This should be pre-alloced so that we could use the same bitmap for all + tables. Would also avoid extra memory allocations if this function would + be called multiple times per query. + */ if (!(buf= (my_bitmap_map*)thd->alloc(table->s->column_bitmap_size))) DBUG_RETURN(TRUE); my_bitmap_init(&handled_columns, buf, table->s->fields); @@ -3395,93 +3483,133 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) */ for (ranges= keynr= 0 ; keynr < table->s->keys; keynr++) if (table->opt_range_keys.is_set(keynr)) - optimal_key_order[ranges++]= keynr; + optimal_key_order[ranges++]= table->opt_range + keynr; - my_qsort2(optimal_key_order, ranges, - sizeof(optimal_key_order[0]), - (qsort2_cmp) cmp_quick_ranges, table); + my_qsort(optimal_key_order, ranges, + sizeof(optimal_key_order[0]), + (qsort_cmp) cmp_quick_ranges); for (range_index= 0 ; range_index < ranges ; range_index++) { - uint keynr= optimal_key_order[range_index]; - { - { - uint i; - uint used_key_parts= table->opt_range[keynr].key_parts; - double quick_cond_selectivity= (table->opt_range[keynr].rows / - table_records); - KEY *key_info= table->key_info + keynr; - KEY_PART_INFO* key_part= key_info->key_part; - /* - Suppose, there are range conditions on two keys - KEY1 (col1, col2) - KEY2 (col3, col2) - - we don't want to count selectivity of condition on col2 twice. - - First, find the longest key prefix that's made of columns whose - selectivity wasn't already accounted for. - */ - for (i= 0; i < used_key_parts; i++, key_part++) - { - if (bitmap_is_set(&handled_columns, key_part->fieldnr-1)) - break; - bitmap_set_bit(&handled_columns, key_part->fieldnr-1); - } - if (i) - { - double UNINIT_VAR(selectivity_mult); + TABLE::OPT_RANGE *range= optimal_key_order[range_index]; + uint keynr= (uint)(range - table->opt_range); + uint i; + uint used_key_parts= range->key_parts; + double quick_cond_selectivity= (range->rows / table_records); + KEY *key_info= table->key_info + keynr; + KEY_PART_INFO* key_part= key_info->key_part; + DBUG_ASSERT(quick_cond_selectivity <= 1.0); - /* - There is at least 1-column prefix of columns whose selectivity has - not yet been accounted for. - */ - table->cond_selectivity*= quick_cond_selectivity; - Json_writer_object selectivity_for_index(thd); - selectivity_for_index.add("index_name", key_info->name) - .add("selectivity_from_index", - quick_cond_selectivity); - if (i != used_key_parts) - { - /* - Range access got us estimate for #used_key_parts. - We need estimate for #(i-1) key parts. - */ - double f1= key_info->actual_rec_per_key(i-1); - double f2= key_info->actual_rec_per_key(i); - if (f1 > 0 && f2 > 0) - selectivity_mult= f1 / f2; - else - { - /* - No statistics available, assume the selectivity is proportional - to the number of key parts. - (i=0 means 1 keypart, i=1 means 2 keyparts, so use i+1) - */ - selectivity_mult= ((double)(i+1)) / i; - } - table->cond_selectivity*= selectivity_mult; - selectivity_for_index.add("selectivity_multiplier", - selectivity_mult); - } + /* + Suppose, there are range conditions on these keys + KEY1 (col1, col2) + KEY2 (col2, col6) + KEY3 (col3, col2) + KEY4 (col4, col5) + + We don't want to count selectivity for ranges that uses a column + that was used before. + If the first column of an index was not used before, we can use the + key part statistics to calculate selectivity for this column. We cannot + calculate statistics for any other columns as the key part statistics + is also depending on the values of the previous key parts and not only + the last key part. + + In other words, if KEY1 has the smallest range, we will only use first + part of KEY3 and range of KEY4 to calculate selectivity. + */ + for (i= 0; i < used_key_parts; i++) + { + if (bitmap_is_set(&handled_columns, key_part[i].fieldnr-1)) + { + double rec_per_key; + if (!i) + { /* - We need to set selectivity for fields supported by indexes. - For single-component indexes and for some first components - of other indexes we do it here. For the remaining fields - we do it later in this function, in the same way as for the - fields not used in any indexes. - */ - if (i == 1) - { - uint fieldnr= key_info->key_part[0].fieldnr; - table->field[fieldnr-1]->cond_selectivity= quick_cond_selectivity; - if (i != used_key_parts) - table->field[fieldnr-1]->cond_selectivity*= selectivity_mult; - bitmap_clear_bit(used_fields, fieldnr-1); - } + We cannot use this key part for selectivity calculation as + key_info->actual_rec_per_key for later keys are depending on the + distribution of the previous key parts. + */ + goto end_of_range_loop; } + /* + A later key part was already used. We can still use key + statistics for the first key part to get some approximation + of the selectivity of this key. This can be done if the + first key part is a constant: + WHERE key1_part1=1 and key2_part1=5 and key2_part2 BETWEEN 0 and 10 + Even if key1 is used and it also includes the field for key2_part1 + as a key part, we can still use selectivity for key2_part1 + */ + if ((rec_per_key= key_info->actual_rec_per_key(0)) == 0.0 || + !range->first_key_part_has_only_one_value) + goto end_of_range_loop; + /* + Use key distribution statistics, except if range selectivity + is bigger. This can happen if the used key value has more + than an average number of instances. + */ + set_if_smaller(rec_per_key, rows2double(table->file->stats.records)); + set_if_bigger(quick_cond_selectivity, + rec_per_key / table->file->stats.records); + used_key_parts= 1; + break; } } + /* Set bits only after we have checked the used columns */ + for (i= 0; i < used_key_parts; i++, key_part++) + bitmap_set_bit(&handled_columns, key_part->fieldnr-1); + + /* + There is at least 1-column prefix of columns whose selectivity has + not yet been accounted for. + */ + table->multiply_cond_selectivity(quick_cond_selectivity); + + if (unlikely(thd->trace_started())) + { + Json_writer_object selectivity_for_index(thd); + selectivity_for_index. + add("index_name", key_info->name). + add("selectivity_from_index", quick_cond_selectivity); + } + /* + We need to set selectivity for fields supported by indexes. + For single-component indexes and for some first components + of other indexes we do it here. For the remaining fields + we do it later in this function, in the same way as for the + fields not used in any indexes. + */ + if (used_key_parts == 1) + { + uint fieldnr= key_info->key_part[0].fieldnr; + table->field[fieldnr-1]->cond_selectivity= quick_cond_selectivity; + DBUG_ASSERT(table->field[fieldnr-1]->cond_selectivity <= 1.0); + /* + Reset bit in used_fields to ensure this field is ignored in the loop + below. + */ + bitmap_clear_bit(used_fields, fieldnr-1); + } +end_of_range_loop: + continue; + } + /* + Take into account number of matching rows calculated by + get_best_ror_intersect() stored in table->opt_range_condition_rows + Use the smaller found selectivity. + */ + original_selectivity= (table->opt_range_condition_rows / + table_records); + if (original_selectivity < table->cond_selectivity) + { + table->cond_selectivity= original_selectivity; + if (unlikely(thd->trace_started())) + { + Json_writer_object selectivity_for_index(thd); + selectivity_for_index.add("use_opt_range_condition_rows_selectivity", + original_selectivity); + } } selectivity_for_indexes.end(); @@ -3502,7 +3630,8 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) double rows; init_sql_alloc(key_memory_quick_range_select_root, &alloc, - thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); + thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); param.thd= thd; param.mem_root= &alloc; param.old_root= thd->mem_root; @@ -3521,9 +3650,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) thd->no_errors=1; - tree= cond[0]->get_mm_tree(¶m, cond); - - if (!tree) + if (!(tree= cond[0]->get_mm_tree(¶m, cond))) goto free_alloc; table->reginfo.impossible_range= 0; @@ -3547,7 +3674,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) for (uint idx= 0; idx < param.keys; idx++) { SEL_ARG *key= tree->keys[idx]; - if (key) + if (key) // Quick range found for key { Json_writer_object selectivity_for_column(thd); selectivity_for_column.add("column_name", key->field->field_name); @@ -3555,8 +3682,10 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) { rows= 0; table->reginfo.impossible_range= 1; - selectivity_for_column.add("selectivity_from_histogram", rows); - selectivity_for_column.add("cause", "impossible range"); + if (unlikely(selectivity_for_column.trace_started())) + selectivity_for_column. + add("selectivity_from_histogram", rows). + add("cause", "impossible range"); goto free_alloc; } else @@ -3565,6 +3694,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) if (rows != DBL_MAX) { key->field->cond_selectivity= rows/table_records; + DBUG_ASSERT(key->field->cond_selectivity <= 1.0); selectivity_for_column.add("selectivity_from_histogram", key->field->cond_selectivity); } @@ -3579,7 +3709,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) table_field->cond_selectivity < 1.0) { if (!bitmap_is_set(&handled_columns, table_field->field_index)) - table->cond_selectivity*= table_field->cond_selectivity; + table->multiply_cond_selectivity(table_field->cond_selectivity); } } @@ -3591,12 +3721,6 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) } selectivity_for_columns.end(); - if (quick && (quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_UNION || - quick->get_type() == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)) - { - table->cond_selectivity*= (quick->records/table_records); - } - bitmap_union(used_fields, &handled_columns); /* Check if we can improve selectivity estimates by using sampling */ @@ -3634,7 +3758,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) DBUG_PRINT("info", ("The predicate selectivity : %g", (double)stat->positive / examined_rows)); double selectivity= ((double)stat->positive) / examined_rows; - table->cond_selectivity*= selectivity; + table->multiply_cond_selectivity(selectivity); /* If a field is involved then we register its selectivity in case there in an equality with the field. @@ -4073,6 +4197,20 @@ end: table->all_partitions_pruned_away= true; retval= TRUE; } + + if (unlikely(thd->trace_started())) + { + String parts; + String_list parts_list; + + make_used_partitions_str(thd->mem_root, prune_param.part_info, &parts, + parts_list); + Json_writer_object trace_wrapper(thd); + Json_writer_object trace_prune(thd, "prune_partitions"); + trace_prune.add_table_name(table); + trace_prune.add("used_partitions", parts.c_ptr()); + } + DBUG_RETURN(retval); } @@ -4985,17 +5123,33 @@ static void dbug_print_singlepoint_range(SEL_ARG **start, uint num) Get cost of 'sweep' full records retrieval. SYNOPSIS get_sweep_read_cost() - param Parameter from test_quick_select - records # of records to be retrieved + param Parameter from test_quick_select + records # of records to be retrieved + add_time_for_compare If set, add cost of WHERE clause (WHERE_COST) RETURN cost of sweep */ -double get_sweep_read_cost(const PARAM *param, ha_rows records) +static double get_sweep_read_cost(const PARAM *param, ha_rows records, + bool add_time_for_compare) { + DBUG_ENTER("get_sweep_read_cost"); +#ifndef OLD_SWEEP_COST + handler *file= param->table->file; + IO_AND_CPU_COST engine_cost= file->ha_rnd_pos_call_time(records); + double cost; + if (add_time_for_compare) + { + engine_cost.cpu+= records * param->thd->variables.optimizer_where_cost; + } + cost= file->cost(engine_cost); + + DBUG_PRINT("return", ("cost: %g", cost)); + DBUG_RETURN(cost); +#else double result; uint pk= param->table->s->primary_key; - DBUG_ENTER("get_sweep_read_cost"); + if (param->table->file->pk_is_clustering_key(pk) || param->table->file->stats.block_size == 0 /* HEAP */) { @@ -5003,12 +5157,12 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) We are using the primary key to find the rows. Calculate the cost for this. */ - result= param->table->file->read_time(pk, (uint)records, records); + result= table->file->ha_rnd_pos_call_time(records); } else { /* - Rows will be retreived with rnd_pos(). Caluclate the expected + Rows will be retreived with rnd_pos(). Calculate the expected cost for this. */ double n_blocks= @@ -5041,9 +5195,11 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) */ result= busy_blocks; } + result+= rows2double(n_rows) * param->table->file->ROW_COPY_COST); } DBUG_PRINT("return",("cost: %g", result)); DBUG_RETURN(result); +#endif /* OLD_SWEEP_COST */ } @@ -5114,7 +5270,9 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) static TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, - double read_time, bool named_trace) + double read_time, ha_rows limit, + bool named_trace, + bool using_table_scan) { SEL_TREE **ptree; TRP_INDEX_MERGE *imerge_trp= NULL; @@ -5178,7 +5336,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, "tree in SEL_IMERGE");); Json_writer_object trace_idx(thd); if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, - read_time))) + read_time, limit, using_table_scan))) { /* One of index scans in this index_merge is more expensive than entire @@ -5197,16 +5355,17 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, imerge_cost += (*cur_child)->read_cost; all_scans_ror_able &= ((*ptree)->n_ror_scans > 0); all_scans_rors &= (*cur_child)->is_ror; - if (param->table->file->is_clustering_key(param->real_keynr[(*cur_child)->key_idx])) + if (param->table->file->is_clustering_key(keynr_in_table)) { cpk_scan= cur_child; cpk_scan_records= (*cur_child)->records; } else non_cpk_scan_records += (*cur_child)->records; - trace_idx.add("index_to_merge", - param->table->key_info[keynr_in_table].name) - .add("cumulated_cost", imerge_cost); + if (unlikely(trace_idx.trace_started())) + trace_idx. + add("index_to_merge", param->table->key_info[keynr_in_table].name). + add("cumulated_cost", imerge_cost); } to_merge.end(); @@ -5238,9 +5397,10 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION)) { roru_read_plans= (TABLE_READ_PLAN**)range_scans; - trace_best_disjunct.add("use_roworder_union", true) - .add("cause", - "always cheaper than non roworder retrieval"); + if (unlikely(trace_best_disjunct.trace_started())) + trace_best_disjunct. + add("use_roworder_union", true). + add("cause", "always cheaper than non roworder retrieval"); goto skip_to_ror_scan; } @@ -5250,8 +5410,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, Add one ROWID comparison for each row retrieved on non-CPK scan. (it is done in QUICK_RANGE_SELECT::row_in_ranges) */ - double rid_comp_cost= (rows2double(non_cpk_scan_records) / - TIME_FOR_COMPARE_ROWID); + double rid_comp_cost= (rows2double(non_cpk_scan_records) * + default_optimizer_costs.rowid_cmp_cost); imerge_cost+= rid_comp_cost; trace_best_disjunct.add("cost_of_mapping_rowid_in_non_clustered_pk_scan", rid_comp_cost); @@ -5259,18 +5419,24 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, /* Calculate cost(rowid_to_row_scan) */ { - double sweep_cost= get_sweep_read_cost(param, non_cpk_scan_records); + /* imerge_cost already includes WHERE_COST */ + double sweep_cost= get_sweep_read_cost(param, non_cpk_scan_records, 0); imerge_cost+= sweep_cost; - trace_best_disjunct.add("cost_sort_rowid_and_read_disk", sweep_cost); + trace_best_disjunct. + add("rows", non_cpk_scan_records). + add("cost_sort_rowid_and_read_disk", sweep_cost). + add("cost", imerge_cost); } DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g", imerge_cost)); if (imerge_cost > read_time || !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION)) { - trace_best_disjunct.add("use_roworder_index_merge", true); - trace_best_disjunct.add("cause", "cost"); - goto build_ror_index_merge; + if (unlikely(trace_best_disjunct.trace_started())) + trace_best_disjunct. + add("use_sort_index_merge", false). + add("cause", imerge_cost > read_time ? "cost" : "disabled"); + goto build_ror_index_merge; // Try roworder_index_merge } /* Add Unique operations cost */ @@ -5287,15 +5453,17 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, } { - const double dup_removal_cost= Unique::get_use_cost( + const double dup_removal_cost= Unique::get_use_cost(thd, param->imerge_cost_buff, (uint)non_cpk_scan_records, param->table->file->ref_length, (size_t)param->thd->variables.sortbuff_size, - TIME_FOR_COMPARE_ROWID, + ROWID_COMPARE_COST_THD(param->thd), FALSE, NULL); imerge_cost+= dup_removal_cost; - trace_best_disjunct.add("cost_duplicate_removal", dup_removal_cost) - .add("total_cost", imerge_cost); + if (unlikely(trace_best_disjunct.trace_started())) + trace_best_disjunct. + add("cost_duplicate_removal", dup_removal_cost). + add("total_cost", imerge_cost); } DBUG_PRINT("info",("index_merge total cost: %g (wanted: less then %g)", @@ -5359,31 +5527,28 @@ skip_to_ror_scan: double cost; if ((*cur_child)->is_ror) { + handler *file= param->table->file; /* Ok, we have index_only cost, now get full rows scan cost */ - cost= param->table->file-> - read_time(param->real_keynr[(*cur_child)->key_idx], 1, - (*cur_child)->records) + - rows2double((*cur_child)->records) / TIME_FOR_COMPARE; + cost= file->cost(file->ha_rnd_pos_call_and_compare_time((*cur_child)->records)); } else cost= read_time; TABLE_READ_PLAN *prev_plan= *cur_child; - if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost, - &dummy))) + TRP_ROR_INTERSECT *ror_trp; + if (!(*cur_roru_plan= ror_trp= get_best_ror_intersect(param, *ptree, cost, + &dummy))) { - if (prev_plan->is_ror) - *cur_roru_plan= prev_plan; - else + if (!prev_plan->is_ror) DBUG_RETURN(imerge_trp); + *cur_roru_plan= prev_plan; roru_index_costs += (*cur_roru_plan)->read_cost; } else - roru_index_costs += - ((TRP_ROR_INTERSECT*)(*cur_roru_plan))->index_scan_costs; + roru_index_costs += ror_trp->index_scan_costs; roru_total_records += (*cur_roru_plan)->records; - roru_intersect_part *= (*cur_roru_plan)->records / - param->table->stat_records(); + roru_intersect_part *= ((*cur_roru_plan)->records / + param->table->stat_records()); } trace_analyze_ror.end(); /* @@ -5404,15 +5569,17 @@ skip_to_ror_scan: */ double roru_total_cost; - roru_total_cost= roru_index_costs + - rows2double(roru_total_records)*log((double)n_child_scans) / - (TIME_FOR_COMPARE_ROWID * M_LN2) + - get_sweep_read_cost(param, roru_total_records); + roru_total_cost= (roru_index_costs + + rows2double(roru_total_records)*log((double)n_child_scans) * + ROWID_COMPARE_COST_THD(param->thd) / M_LN2 + + get_sweep_read_cost(param, roru_total_records, 0)); DBUG_PRINT("info", ("ROR-union: cost %g, %zu members", roru_total_cost, n_child_scans)); - trace_best_disjunct.add("index_roworder_union_cost", roru_total_cost) - .add("members", n_child_scans); + if (unlikely(trace_best_disjunct.trace_started())) + trace_best_disjunct. + add("index_roworder_union_cost", roru_total_cost). + add("members", n_child_scans); TRP_ROR_UNION* roru; if (roru_total_cost < read_time) { @@ -5438,7 +5605,7 @@ skip_to_ror_scan: SYNOPSIS merge_same_index_scans() param Context info for the operation - imerge IN/OUT SEL_IMERGE from which imerge_trp has been extracted + imerge IN/OUT SEL_IMERGE from which imerge_trp has been extracted imerge_trp The index merge plan where index scans for the same indexes are to be merges read_time The upper bound for the cost of the plan to be evaluated @@ -5519,7 +5686,8 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, DBUG_ASSERT(imerge->trees_next>imerge->trees); if (imerge->trees_next-imerge->trees > 1) - trp= get_best_disjunct_quick(param, imerge, read_time, true); + trp= get_best_disjunct_quick(param, imerge, read_time, HA_POS_ERROR, true, + 0); else { /* @@ -5560,8 +5728,8 @@ typedef struct st_common_index_intersect_info { PARAM *param; /* context info for range optimizations */ uint key_size; /* size of a ROWID element stored in Unique object */ - double compare_factor; /* 1/compare - cost to compare two ROWIDs */ - size_t max_memory_size; /* maximum space allowed for Unique objects */ + double compare_factor; /* cost to compare two ROWIDs */ + size_t max_memory_size; /* maximum space allowed for Unique objects */ ha_rows table_cardinality; /* estimate of the number of records in table */ double cutoff_cost; /* discard index intersects with greater costs */ INDEX_SCAN_INFO *cpk_scan; /* clustered primary key used in intersection */ @@ -5661,8 +5829,7 @@ bool create_fields_bitmap(PARAM *param, MY_BITMAP *fields_bitmap) static int cmp_intersect_index_scan(INDEX_SCAN_INFO **a, INDEX_SCAN_INFO **b) { - return (*a)->records < (*b)->records ? - -1 : (*a)->records == (*b)->records ? 0 : 1; + return CMP_NUM((*a)->records, (*b)->records); } @@ -5775,7 +5942,7 @@ bool prepare_search_best_index_intersect(PARAM *param, common->param= param; common->key_size= table->file->ref_length; - common->compare_factor= TIME_FOR_COMPARE_ROWID; + common->compare_factor= ROWID_COMPARE_COST_THD(param->thd); common->max_memory_size= (size_t)param->thd->variables.sortbuff_size; common->cutoff_cost= cutoff_cost; common->cpk_scan= NULL; @@ -5816,26 +5983,30 @@ bool prepare_search_best_index_intersect(PARAM *param, if (*index_scan == cpk_scan) { - idx_scan.add("chosen", "false") - .add("cause", "clustered index used for filtering"); + if (unlikely(idx_scan.trace_started())) + idx_scan. + add("chosen", "false"). + add("cause", "clustered index used for filtering"); continue; } if (cpk_scan && cpk_scan->used_key_parts >= used_key_parts && same_index_prefix(cpk_scan->key_info, key_info, used_key_parts)) { - idx_scan.add("chosen", "false") - .add("cause", "clustered index used for filtering"); + if (unlikely(idx_scan.trace_started())) + idx_scan. + add("chosen", "false"). + add("cause", "clustered index used for filtering"); continue; } - cost= table->opt_range[(*index_scan)->keynr].index_only_cost; + cost= table->opt_range[(*index_scan)->keynr].index_only_fetch_cost(table); idx_scan.add("cost", cost); - if (cost >= cutoff_cost) + if (cost + COST_EPS >= cutoff_cost) { - idx_scan.add("chosen", false); - idx_scan.add("cause", "cost"); + if (unlikely(idx_scan.trace_started())) + idx_scan.add("chosen", false).add("cause", "cost"); continue; } @@ -5854,15 +6025,18 @@ bool prepare_search_best_index_intersect(PARAM *param, } if (!*scan_ptr || cost < (*scan_ptr)->index_read_cost) { - idx_scan.add("chosen", true); - if (!*scan_ptr) - idx_scan.add("cause", "first occurrence of index prefix"); - else - idx_scan.add("cause", "better cost for same idx prefix"); + if (unlikely(idx_scan.trace_started())) + { + idx_scan.add("chosen", true); + if (!*scan_ptr) + idx_scan.add("cause", "first occurrence of index prefix"); + else + idx_scan.add("cause", "better cost for same idx prefix"); + } *scan_ptr= *index_scan; (*scan_ptr)->index_read_cost= cost; } - else + else if (unlikely(idx_scan.trace_started())) { idx_scan.add("chosen", false).add("cause", "cost"); } @@ -5887,7 +6061,7 @@ bool prepare_search_best_index_intersect(PARAM *param, return TRUE; common->best_uses_cpk= FALSE; - common->best_cost= cutoff_cost + COST_EPS; + common->best_cost= cutoff_cost; common->best_length= 0; if (!(common->best_intersect= @@ -5925,13 +6099,14 @@ bool prepare_search_best_index_intersect(PARAM *param, ha_rows records= records_in_index_intersect_extension(&curr, *scan_ptr); (*scan_ptr)->filtered_out= records >= scan_records ? 0 : scan_records-records; - if (thd->trace_started()) + if (unlikely(thd->trace_started())) { Json_writer_object selected_idx(thd); selected_idx.add("index", key_info->name); print_keyparts(thd, key_info, (*scan_ptr)->used_key_parts); - selected_idx.add("records", (*scan_ptr)->records) - .add("filtered_records", (*scan_ptr)->filtered_out); + selected_idx. + add("rows", (*scan_ptr)->records). + add("filtered_records", (*scan_ptr)->filtered_out); } } } @@ -5941,13 +6116,14 @@ bool prepare_search_best_index_intersect(PARAM *param, { KEY *key_info= (*scan_ptr)->key_info; (*scan_ptr)->filtered_out= 0; - if (thd->trace_started()) + if (unlikely(thd->trace_started())) { Json_writer_object selected_idx(thd); selected_idx.add("index", key_info->name); print_keyparts(thd, key_info, (*scan_ptr)->used_key_parts); - selected_idx.add("records", (*scan_ptr)->records) - .add("filtered_records", (*scan_ptr)->filtered_out); + selected_idx. + add("rows", (*scan_ptr)->records). + add("filtered_records", (*scan_ptr)->filtered_out); } } } @@ -6187,8 +6363,8 @@ double get_cpk_filter_cost(ha_rows filtered_records, INDEX_SCAN_INFO *cpk_scan, double compare_factor) { - return log((double) (cpk_scan->range_count+1)) / (compare_factor * M_LN2) * - filtered_records; + return (log((double) (cpk_scan->range_count+1)) * compare_factor / M_LN2 * + filtered_records); } @@ -6212,7 +6388,8 @@ double get_cpk_filter_cost(ha_rows filtered_records, */ static -bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, +bool check_index_intersect_extension(THD *thd, + PARTIAL_INDEX_INTERSECT_INFO *curr, INDEX_SCAN_INFO *ext_index_scan, PARTIAL_INDEX_INTERSECT_INFO *next) { @@ -6224,9 +6401,19 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, COMMON_INDEX_INTERSECT_INFO *common_info= curr->common_info; double cutoff_cost= common_info->cutoff_cost; uint idx= curr->length; + Json_writer_object trace(thd, "check_index_intersect_extension"); + next->index_read_cost= curr->index_read_cost+ext_index_scan->index_read_cost; if (next->index_read_cost > cutoff_cost) - return FALSE; + { + if (unlikely(trace.trace_started())) + trace. + add("index", ext_index_scan->key_info->name.str). + add("cost", next->index_read_cost). + add("chosen", false). + add("cause", "cost"); + return FALSE; + } if ((next->in_memory= curr->in_memory)) next->in_memory_cost= curr->in_memory_cost; @@ -6250,16 +6437,18 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, common_info->compare_factor)* ext_index_scan_records; cost= next->in_memory_cost; + } else { uint *buff_elems= common_info->buff_elems; uint key_size= common_info->key_size; double compare_factor= common_info->compare_factor; - size_t max_memory_size= common_info->max_memory_size; - + size_t max_memory_size= common_info->max_memory_size; + records_sent_to_unique+= ext_index_scan_records; - cost= Unique::get_use_cost(buff_elems, (size_t) records_sent_to_unique, key_size, + cost= Unique::get_use_cost(thd, buff_elems, (size_t) records_sent_to_unique, + key_size, max_memory_size, compare_factor, TRUE, &next->in_memory); if (records_filtered_out_by_cpk) @@ -6269,7 +6458,7 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, double cost2; bool in_memory2; ha_rows records2= records_sent_to_unique-records_filtered_out_by_cpk; - cost2= Unique::get_use_cost(buff_elems, (size_t) records2, key_size, + cost2= Unique::get_use_cost(thd, buff_elems, (size_t) records2, key_size, max_memory_size, compare_factor, TRUE, &in_memory2); cost2+= get_cpk_filter_cost(ext_index_scan_records, common_info->cpk_scan, @@ -6286,6 +6475,19 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, if (next->in_memory) next->in_memory_cost= cost; } + if (unlikely(trace.trace_started())) + { + trace. + add("index", ext_index_scan->key_info->name.str). + add("in_memory", next->in_memory). + add("range_rows", ext_index_scan_records). + add("rows_sent_to_unique", records_sent_to_unique). + add("unique_cost", cost). + add("index_read_cost", next->index_read_cost); + if (next->use_cpk_filter) + trace.add("rows_filtered_out_by_clustered_pk", records_filtered_out_by_cpk); + } + if (next->use_cpk_filter) { @@ -6297,20 +6499,37 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, records= records_in_index_intersect_extension(curr, ext_index_scan); if (idx && records > curr->records) + { + if (unlikely(trace.trace_started())) + trace. + add("rows", records). + add("chosen", false). + add("cause", "too many rows"); return FALSE; + } if (next->use_cpk_filter && curr->filtered_scans.is_clear_all()) records-= records_filtered_out_by_cpk; next->records= records; cost+= next->index_read_cost; if (cost >= cutoff_cost) + { + if (unlikely(trace.trace_started())) + trace.add("cost", cost).add("chosen", false).add("cause", "cost"); return FALSE; + } - cost+= get_sweep_read_cost(common_info->param, records); + /* + The cost after sweeep can be bigger than cutoff, but that is ok as the + end cost can decrease when we add the next index. + */ + cost+= get_sweep_read_cost(common_info->param, records, 1); next->cost= cost; next->length= curr->length+1; + if (unlikely(trace.trace_started())) + trace.add("rows", records).add("cost", cost).add("chosen", true); return TRUE; } @@ -6329,7 +6548,8 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, */ static -void find_index_intersect_best_extension(PARTIAL_INDEX_INTERSECT_INFO *curr) +void find_index_intersect_best_extension(THD *thd, + PARTIAL_INDEX_INTERSECT_INFO *curr) { PARTIAL_INDEX_INTERSECT_INFO next; COMMON_INDEX_INTERSECT_INFO *common_info= curr->common_info; @@ -6356,14 +6576,18 @@ void find_index_intersect_best_extension(PARTIAL_INDEX_INTERSECT_INFO *curr) next.common_info= common_info; + Json_writer_array potential_index_intersect(thd, "potential_index_intersect"); + INDEX_SCAN_INFO *rem_first_index_scan= *rem_first_index_scan_ptr; for (INDEX_SCAN_INFO **index_scan_ptr= rem_first_index_scan_ptr; *index_scan_ptr; index_scan_ptr++) { + Json_writer_object selected(thd); *rem_first_index_scan_ptr= *index_scan_ptr; *index_scan_ptr= rem_first_index_scan; - if (check_index_intersect_extension(curr, *rem_first_index_scan_ptr, &next)) - find_index_intersect_best_extension(&next); + if (check_index_intersect_extension(thd, curr, *rem_first_index_scan_ptr, + &next)) + find_index_intersect_best_extension(thd, &next); *index_scan_ptr= *rem_first_index_scan_ptr; *rem_first_index_scan_ptr= rem_first_index_scan; } @@ -6407,16 +6631,18 @@ TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, TRP_INDEX_INTERSECT *intersect_trp= NULL; TABLE *table= param->table; THD *thd= param->thd; - DBUG_ENTER("get_best_index_intersect"); Json_writer_object trace_idx_interect(thd, "analyzing_sort_intersect"); + if (unlikely(trace_idx_interect.trace_started())) + trace_idx_interect.add("cutoff_cost", read_time); + if (prepare_search_best_index_intersect(param, tree, &common, &init, read_time)) DBUG_RETURN(NULL); - find_index_intersect_best_extension(&init); + find_index_intersect_best_extension(thd, &init); if (common.best_length <= 1 && !common.best_uses_cpk) DBUG_RETURN(NULL); @@ -6475,13 +6701,15 @@ TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, { intersect_trp->read_cost= common.best_cost; - intersect_trp->records= common.best_records; + intersect_trp->records= common.best_records; intersect_trp->range_scans= range_scans; intersect_trp->range_scans_end= cur_range; intersect_trp->filtered_scans= common.filtered_scans; - trace_idx_interect.add("rows", intersect_trp->records) - .add("cost", intersect_trp->read_cost) - .add("chosen",true); + if (unlikely(trace_idx_interect.trace_started())) + trace_idx_interect. + add("rows", intersect_trp->records). + add("cost", intersect_trp->read_cost). + add("chosen",true); } DBUG_RETURN(intersect_trp); } @@ -6497,11 +6725,12 @@ void TRP_ROR_INTERSECT::trace_basic_info(PARAM *param, THD *thd= param->thd; DBUG_ASSERT(trace_object->trace_started()); - trace_object->add("type", "index_roworder_intersect"); - trace_object->add("rows", records); - trace_object->add("cost", read_cost); - trace_object->add("covering", is_covering); - trace_object->add("clustered_pk_scan", cpk_scan != NULL); + trace_object-> + add("type", "index_roworder_intersect"). + add("rows", records). + add("cost", read_cost). + add("covering", is_covering). + add("clustered_pk_scan", cpk_scan != NULL); Json_writer_array smth_trace(thd, "intersect_of"); for (ROR_SCAN_INFO **cur_scan= first_scan; cur_scan != last_scan; @@ -6511,9 +6740,10 @@ void TRP_ROR_INTERSECT::trace_basic_info(PARAM *param, const KEY_PART_INFO *key_part= cur_key.key_part; Json_writer_object trace_isect_idx(thd); - trace_isect_idx.add("type", "range_scan"); - trace_isect_idx.add("index", cur_key.name); - trace_isect_idx.add("rows", (*cur_scan)->records); + trace_isect_idx. + add("type", "range_scan"). + add("index", cur_key.name). + add("rows", (*cur_scan)->records); Json_writer_array trace_range(thd, "ranges"); @@ -6544,6 +6774,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) ROR_SCAN_INFO *ror_scan; my_bitmap_map *bitmap_buf; uint keynr; + handler *file= param->table->file; DBUG_ENTER("make_ror_scan"); if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root, @@ -6553,7 +6784,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) ror_scan->idx= idx; ror_scan->keynr= keynr= param->real_keynr[idx]; ror_scan->key_rec_length= (param->table->key_info[keynr].key_length + - param->table->file->ref_length); + file->ref_length); ror_scan->sel_arg= sel_arg; ror_scan->records= param->quick_rows[keynr]; @@ -6574,8 +6805,14 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) if (bitmap_is_set(¶m->needed_fields, key_part->fieldnr-1)) bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1); } + + /* + Cost of reading the keys for the rows, which are later stored in the + ror queue. + */ ror_scan->index_read_cost= - param->table->file->keyread_time(ror_scan->keynr, 1, ror_scan->records); + file->cost(file->ha_keyread_and_copy_time(ror_scan->keynr, 1, + ror_scan->records, 0)); DBUG_RETURN(ror_scan); } @@ -6885,7 +7122,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, avoid duplicating the inference code) NOTES - Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR- + Adding a ROR scan to ROR-intersect "makes sense" if the cost of ROR- intersection decreases. The cost of ROR-intersection is calculated as follows: @@ -6933,11 +7170,11 @@ static bool ror_intersect_add(ROR_INTERSECT_INFO *info, { /* CPK scan is used to filter out rows. We apply filtering for - each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID + each record of every scan. Assuming ROWID_COMPARE_COST per check this gives us: */ - const double idx_cost= rows2double(info->index_records) / - TIME_FOR_COMPARE_ROWID; + const double idx_cost= (rows2double(info->index_records) * + ROWID_COMPARE_COST_THD(info->param->thd)); info->index_scan_costs+= idx_cost; trace_costs->add("index_scan_cost", idx_cost); } @@ -6961,13 +7198,15 @@ static bool ror_intersect_add(ROR_INTERSECT_INFO *info, if (!info->is_covering) { double sweep_cost= get_sweep_read_cost(info->param, - double2rows(info->out_rows)); + double2rows(info->out_rows), 1); info->total_cost+= sweep_cost; trace_costs->add("disk_sweep_cost", sweep_cost); DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); } else - trace_costs->add("disk_sweep_cost", 0); + { + trace_costs->add("disk_sweep_cost", static_cast(0)); + } DBUG_PRINT("info", ("New out_rows: %g", info->out_rows)); DBUG_PRINT("info", ("New cost: %g, %scovering", info->total_cost, @@ -7046,9 +7285,13 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, bool *are_all_covering) { uint idx; - double min_cost= DBL_MAX; - DBUG_ENTER("get_best_ror_intersect"); + double min_cost= DBL_MAX, cmp_cost; THD *thd= param->thd; + DBUG_ENTER("get_best_ror_intersect"); + DBUG_PRINT("enter", ("opt_range_condition_rows: %llu cond_selectivity: %g", + (ulonglong) param->table->opt_range_condition_rows, + param->table->cond_selectivity)); + Json_writer_object trace_ror(thd, "analyzing_roworder_intersect"); if ((tree->n_ror_scans < 2) || !param->table->stat_records() || @@ -7082,8 +7325,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, if (!tree->ror_scans_map.is_set(idx)) continue; key_no= param->real_keynr[idx]; - if (key_no != cpk_no && - param->table->file->index_flags(key_no,0,0) & HA_CLUSTERED_INDEX) + if (key_no != cpk_no && param->table->file->is_clustering_key(key_no)) { /* Ignore clustering keys */ tree->n_ror_scans--; @@ -7143,31 +7385,40 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, /* S= S + first(R); R= R - first(R); */ if (!ror_intersect_add(intersect, *cur_ror_scan, &trace_idx, FALSE)) { - trace_idx.add("usable", false) - .add("cause", "does not reduce cost of intersect"); + trace_idx. + add("usable", false). + add("cause", "does not reduce cost of intersect"); cur_ror_scan++; continue; } - trace_idx.add("cumulative_total_cost", intersect->total_cost) - .add("usable", true) - .add("matching_rows_now", intersect->out_rows) - .add("intersect_covering_with_this_index", intersect->is_covering); + trace_idx. + add("cumulative_total_cost", intersect->total_cost). + add("usable", true). + add("matching_rows_now", intersect->out_rows). + add("intersect_covering_with_this_index", intersect->is_covering); *(intersect_scans_end++)= *(cur_ror_scan++); + /* + Check if intersect gives a lower cost. + The first ror scan is always accepted. + The next ror scan is only accepted if the total cost went down + (Enough rows where reject to offset the intersect cost) + */ if (intersect->total_cost < min_cost) { /* Local minimum found, save it */ + min_cost= intersect->total_cost; ror_intersect_cpy(intersect_best, intersect); intersect_scans_best= intersect_scans_end; - min_cost = intersect->total_cost; trace_idx.add("chosen", true); } else { - trace_idx.add("chosen", false) - .add("cause", "does not reduce cost"); + trace_idx. + add("chosen", false). + add("cause", "does not reduce cost"); } } trace_isect_idx.end(); @@ -7175,8 +7426,9 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, if (intersect_scans_best == intersect_scans) { DBUG_PRINT("info", ("None of scans increase selectivity")); - trace_ror.add("chosen", false) - .add("cause","does not increase selectivity"); + trace_ror. + add("chosen", false). + add("cause","does not increase selectivity"); DBUG_RETURN(NULL); } @@ -7200,32 +7452,46 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, if (ror_intersect_add(intersect, cpk_scan, &trace_cpk, TRUE) && (intersect->total_cost < min_cost)) { - trace_cpk.add("clustered_pk_scan_added_to_intersect", true) - .add("cumulated_cost", intersect->total_cost); + min_cost= intersect->total_cost; + if (trace_cpk.trace_started()) + trace_cpk. + add("clustered_pk_scan_added_to_intersect", true). + add("cumulated_cost", intersect->total_cost); intersect_best= intersect; //just set pointer here } else { - trace_cpk.add("clustered_pk_added_to_intersect", false) - .add("cause", "cost"); + if (trace_cpk.trace_started()) + trace_cpk. + add("clustered_pk_added_to_intersect", false). + add("cause", "cost"); cpk_scan= 0; // Don't use cpk_scan } } else { - trace_cpk.add("clustered_pk_added_to_intersect", false) - .add("cause", cpk_scan ? "roworder is covering" - : "no clustered pk index"); + trace_cpk. + add("clustered_pk_added_to_intersect", false). + add("cause", cpk_scan ? "roworder is covering" + : "no clustered pk index"); cpk_scan= 0; // Don't use cpk_scan } trace_cpk.end(); + /* + Adjust row count and add the cost of comparing the final rows to the + WHERE clause + */ + cmp_cost= intersect_best->out_rows * thd->variables.optimizer_where_cost; + /* Ok, return ROR-intersect plan if we have found one */ TRP_ROR_INTERSECT *trp= NULL; - if (min_cost < read_time && (cpk_scan || best_num > 1)) + if (min_cost + cmp_cost < read_time && (cpk_scan || best_num > 1)) { + double best_rows= intersect_best->out_rows; + set_if_bigger(best_rows, 1); if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT)) - DBUG_RETURN(trp); + DBUG_RETURN(NULL); if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root, sizeof(ROR_SCAN_INFO*)*best_num))) @@ -7233,30 +7499,30 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*)); trp->last_scan= trp->first_scan + best_num; trp->is_covering= intersect_best->is_covering; - trp->read_cost= intersect_best->total_cost; - /* Prevent divisons by zero */ - ha_rows best_rows = double2rows(intersect_best->out_rows); - if (!best_rows) - best_rows= 1; - set_if_smaller(param->table->opt_range_condition_rows, best_rows); - trp->records= best_rows; + trp->read_cost= min_cost + cmp_cost; + param->table->set_opt_range_condition_rows((ha_rows)best_rows); + trp->records= (ha_rows)best_rows; trp->index_scan_costs= intersect_best->index_scan_costs; trp->cpk_scan= cpk_scan; DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:" "cost %g, records %lu", trp->read_cost, (ulong) trp->records)); - trace_ror.add("rows", trp->records) - .add("cost", trp->read_cost) - .add("covering", trp->is_covering) - .add("chosen", true); + if (unlikely(trace_ror.trace_started())) + trace_ror. + add("rows", trp->records). + add("cost", trp->read_cost). + add("covering", trp->is_covering). + add("chosen", true); } else { - trace_ror.add("chosen", false) - .add("cause", (read_time > min_cost) - ? "too few indexes to merge" - : "cost"); + trace_ror. + add("chosen", false). + add("cause", (min_cost + cmp_cost >= read_time) ? + "cost" : "too few indexes to merge"); } + DBUG_PRINT("exit", ("opt_range_condition_rows: %llu", + (ulonglong) param->table->opt_range_condition_rows)); DBUG_RETURN(trp); } @@ -7328,7 +7594,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, DBUG_RETURN(0); bitmap_clear_all(covered_fields); - double total_cost= 0.0f; + double total_cost= 0.0; ha_rows records=0; bool all_covered; @@ -7385,11 +7651,13 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, tree->ror_scans, ror_scan_mark);); /* Add priority queue use cost. */ - total_cost += rows2double(records)* - log((double)(ror_scan_mark - tree->ror_scans)) / - (TIME_FOR_COMPARE_ROWID * M_LN2); + total_cost += (rows2double(records) * + log((double)(ror_scan_mark - tree->ror_scans)) * + ROWID_COMPARE_COST_THD(param->thd) / M_LN2); DBUG_PRINT("info", ("Covering ROR-intersect full cost: %g", total_cost)); + /* TODO: Add TIME_FOR_COMPARE cost to total_cost */ + if (total_cost > read_time) DBUG_RETURN(NULL); @@ -7407,9 +7675,9 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, trp->read_cost= total_cost; trp->records= records; trp->cpk_scan= NULL; - set_if_smaller(param->table->opt_range_condition_rows, records); + param->table->set_opt_range_condition_rows(records); - DBUG_PRINT("info", + DBUG_PRINT("exit", ("Returning covering ROR-intersect plan: cost %g, records %lu", trp->read_cost, (ulong) trp->records)); DBUG_RETURN(trp); @@ -7436,7 +7704,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, bool index_read_must_be_used, bool for_range_access, - double read_time) + double read_time, ha_rows limit, + bool using_table_scan) { uint idx, UNINIT_VAR(best_idx); SEL_ARG *key_to_read= NULL; @@ -7488,23 +7757,23 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, Json_writer_object trace_idx(thd); trace_idx.add("index", param->table->key_info[keynr].name); - found_records= check_quick_select(param, idx, read_index_only, key, - for_range_access, &mrr_flags, + found_records= check_quick_select(param, idx, limit, read_index_only, + key, for_range_access, &mrr_flags, &buf_size, &cost, &is_ror_scan); - if (!for_range_access && !is_ror_scan && - !optimizer_flag(param->thd,OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION)) + if (found_records == HA_POS_ERROR || + (!for_range_access && !is_ror_scan && + !optimizer_flag(param->thd,OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))) { /* The scan is not a ROR-scan, just skip it */ continue; } - - if (found_records != HA_POS_ERROR && tree->index_scans && + found_read_time= cost.total_cost(); + if (tree->index_scans && (index_scan= (INDEX_SCAN_INFO *)alloc_root(param->mem_root, sizeof(INDEX_SCAN_INFO)))) { Json_writer_array trace_range(thd, "ranges"); - const KEY &cur_key= param->table->key_info[keynr]; const KEY_PART_INFO *key_part= cur_key.key_part; @@ -7521,19 +7790,30 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, trace_ranges(&trace_range, param, idx, key, key_part); trace_range.end(); - trace_idx.add("rowid_ordered", is_ror_scan) - .add("using_mrr", !(mrr_flags & HA_MRR_USE_DEFAULT_IMPL)) - .add("index_only", read_index_only) - .add("rows", found_records) - .add("cost", cost.total_cost()); + if (unlikely(trace_idx.trace_started())) + { + trace_idx. + add("rowid_ordered", is_ror_scan). + add("using_mrr", !(mrr_flags & HA_MRR_USE_DEFAULT_IMPL)). + add("index_only", read_index_only). + add("rows", found_records). + add("cost", found_read_time); + if (using_table_scan && cost.limit_cost != 0.0) + trace_idx.add("cost_with_limit", cost.limit_cost); + } } - if ((found_records != HA_POS_ERROR) && is_ror_scan) + if (is_ror_scan) { tree->n_ror_scans++; tree->ror_scans_map.set_bit(idx); } - if (found_records != HA_POS_ERROR && - read_time > (found_read_time= cost.total_cost())) + /* + Use range if best range so far or if we are comparing to a table scan + and the cost with limit approximation is better than the table scan + */ + if (read_time > found_read_time || + (using_table_scan && cost.limit_cost != 0.0 && + read_time > cost.limit_cost)) { read_time= found_read_time; best_records= found_records; @@ -7541,9 +7821,10 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, best_idx= idx; best_mrr_flags= mrr_flags; best_buf_size= buf_size; + using_table_scan= 0; trace_idx.add("chosen", true); } - else + else if (unlikely(trace_idx.trace_started())) { trace_idx.add("chosen", false); if (found_records == HA_POS_ERROR) @@ -10873,6 +11154,50 @@ uint SEL_ARG::get_max_key_part() const } +/** + Compute the number of eq_ranges top elements in the tree + + This is used by the cost_group_min_max() to calculate the number of + groups in SEL_TREE + + @param group_key_parts number of key parts that must be equal + + @return < 0 Not known + @return >= 0 Number of groups +*/ + +int SEL_ARG::number_of_eq_groups(uint group_key_parts) const +{ + int elements= 0; + SEL_ARG const *cur; + + if (part > group_key_parts-1 || type != KEY_RANGE) + return -1; + + cur= first(); + do + { + if ((cur->min_flag | cur->min_flag) & + (NO_MIN_RANGE | NO_MAX_RANGE | NEAR_MIN | NEAR_MAX | GEOM_FLAG)) + return -1; + if (min_value != max_value && !min_max_are_equal()) + return -1; + if (part != group_key_parts -1) + { + int tmp; + if (!next_key_part) + return -1; + if ((tmp= next_key_part->number_of_eq_groups(group_key_parts)) < 0) + return -1; + elements+= tmp; + } + else + elements++; + } while ((cur= cur->next)); + return elements; +} + + /* Remove the SEL_ARG graph elements which have part > max_part. @@ -10925,8 +11250,8 @@ void prune_sel_arg_graph(SEL_ARG *sel_arg, uint max_part) @return tree pointer The tree after processing, - NULL If it was not possible to reduce the weight of the tree below the - limit. + NULL If it was not possible to reduce the weight of the tree below + the limit. */ SEL_ARG *enforce_sel_arg_weight_limit(RANGE_OPT_PARAM *param, uint keyno, @@ -10962,7 +11287,7 @@ SEL_ARG *enforce_sel_arg_weight_limit(RANGE_OPT_PARAM *param, uint keyno, uint weight2= sel_arg? sel_arg->weight : 0; - if (weight2 != weight1) + if (unlikely(weight2 != weight1 && param->thd->trace_started())) { Json_writer_object wrapper(param->thd); Json_writer_object obj(param->thd, "enforce_sel_arg_weight_limit"); @@ -10971,8 +11296,9 @@ SEL_ARG *enforce_sel_arg_weight_limit(RANGE_OPT_PARAM *param, uint keyno, else obj.add("pseudo_index", field->field_name); - obj.add("old_weight", (longlong)weight1); - obj.add("new_weight", (longlong)weight2); + obj. + add("old_weight", (longlong)weight1). + add("new_weight", (longlong)weight2); } return sel_arg; } @@ -10996,12 +11322,16 @@ bool sel_arg_and_weight_heuristic(RANGE_OPT_PARAM *param, SEL_ARG *key1, ulong max_weight= param->thd->variables.optimizer_max_sel_arg_weight; if (max_weight && key1->weight + key1->elements*key2->weight > max_weight) { - Json_writer_object wrapper(param->thd); - Json_writer_object obj(param->thd, "sel_arg_weight_heuristic"); - obj.add("key1_field", key1->field->field_name); - obj.add("key2_field", key2->field->field_name); - obj.add("key1_weight", (longlong)key1->weight); - obj.add("key2_weight", (longlong)key2->weight); + if (unlikely(param->thd->trace_started())) + { + Json_writer_object wrapper(param->thd); + Json_writer_object obj(param->thd, "sel_arg_weight_heuristic"); + obj. + add("key1_field", key1->field->field_name). + add("key2_field", key2->field->field_name). + add("key1_weight", (longlong)key1->weight). + add("key2_weight", (longlong)key2->weight); + } return true; // Discard key2 } return false; @@ -11491,6 +11821,26 @@ void SEL_ARG::test_use_count(SEL_ARG *root) } #endif + +/** + Check if first key part has only one value + + @retval 1 yes + @retval 0 no +*/ + +static bool check_if_first_key_part_has_only_one_value(SEL_ARG *arg) +{ + if (arg->left != &null_element || arg->right != &null_element) + return 0; // Multiple key values + if ((arg->min_flag | arg->max_flag) & (NEAR_MIN | NEAR_MAX)) + return 0; + if (unlikely(arg->type != SEL_ARG::KEY_RANGE)) // Not a valid range + return 0; + return arg->min_value == arg->max_value || !arg->cmp_min_to_max(arg); +} + + /* Calculate cost and E(#rows) for a given index and intervals tree @@ -11519,13 +11869,15 @@ void SEL_ARG::test_use_count(SEL_ARG *root) */ static -ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, +ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit, + bool index_only, SEL_ARG *tree, bool update_tbl_stats, uint *mrr_flags, uint *bufsize, Cost_estimate *cost, bool *is_ror_scan) { SEL_ARG_RANGE_SEQ seq; - RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0}; + RANGE_SEQ_IF seq_if= + {NULL, sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0}; handler *file= param->table->file; ha_rows rows= HA_POS_ERROR; uint keynr= param->real_keynr[idx]; @@ -11552,7 +11904,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, param->max_key_parts=0; seq.is_ror_scan= TRUE; - if (file->index_flags(keynr, 0, TRUE) & HA_KEY_SCAN_NOT_ROR) + if (param->table->key_info[keynr].index_flags & HA_KEY_SCAN_NOT_ROR) seq.is_ror_scan= FALSE; *mrr_flags= param->force_default_mrr? HA_MRR_USE_DEFAULT_IMPL: 0; @@ -11565,9 +11917,9 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, // Passing wrong second argument to index_flags() makes no difference for // most storage engines but might be an issue for MyRocks with certain // datatypes. + // Note that HA_KEYREAD_ONLY implies that this is not a clustered index if (index_only && - (file->index_flags(keynr, param->max_key_parts, 1) & HA_KEYREAD_ONLY) && - !(file->index_flags(keynr, param->max_key_parts, 1) & HA_CLUSTERED_INDEX)) + (file->index_flags(keynr, param->max_key_parts, 1) & HA_KEYREAD_ONLY)) *mrr_flags |= HA_MRR_INDEX_ONLY; if (param->thd->lex->sql_command != SQLCOM_SELECT) @@ -11580,7 +11932,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, */ if (param->table->pos_in_table_list->is_non_derived()) rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0, - bufsize, mrr_flags, cost); + bufsize, mrr_flags, limit, cost); param->quick_rows[keynr]= rows; if (rows != HA_POS_ERROR) { @@ -11593,24 +11945,28 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, This check is needed as sometimes that table statistics or range estimates may be slightly out of sync. */ - rows= table_records; - set_if_bigger(rows, 1); + rows= MY_MAX(table_records, 1); param->quick_rows[keynr]= rows; } param->possible_keys.set_bit(keynr); if (update_tbl_stats) { + TABLE::OPT_RANGE *range= param->table->opt_range + keynr; param->table->opt_range_keys.set_bit(keynr); - param->table->opt_range[keynr].key_parts= param->max_key_parts; - param->table->opt_range[keynr].ranges= param->range_count; - param->table->opt_range_condition_rows= - MY_MIN(param->table->opt_range_condition_rows, rows); - param->table->opt_range[keynr].rows= rows; - param->table->opt_range[keynr].cost= cost->total_cost(); - if (param->table->file->is_clustering_key(keynr)) - param->table->opt_range[keynr].index_only_cost= 0; - else - param->table->opt_range[keynr].index_only_cost= cost->index_only_cost(); + range->key_parts= param->max_key_parts; + range->ranges= param->range_count; + param->table->set_opt_range_condition_rows(rows); + range->selectivity= (rows ? + (param->table->opt_range_condition_rows / + rows) : + 1.0); // ok as rows is 0 + range->rows= rows; + range->cost= *cost; + range->max_index_blocks= file->index_blocks(keynr, range->ranges, + rows); + range->max_row_blocks= MY_MIN(file->row_blocks(), rows * file->stats.block_size / IO_SIZE); + range->first_key_part_has_only_one_value= + check_if_first_key_part_has_only_one_value(tree); } } @@ -11643,6 +11999,8 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, *is_ror_scan= seq.is_ror_scan; DBUG_PRINT("exit", ("Records: %lu", (ulong) rows)); + DBUG_ASSERT(rows == HA_POS_ERROR || + rows <= MY_MAX(param->table->stat_records(), 1)); DBUG_RETURN(rows); //psergey-merge:todo: maintain first_null_comp. } @@ -13627,6 +13985,12 @@ cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts, The group-by list is a permutation of the select attributes, according to their order in the index. + EXAMPLES of handled queries + select max(keypart2) from t1 group by keypart1 + select max(keypart2) from t1 where keypart2 <= const group by keypart1 + select distinct keypart1 from table; + select count(distinct keypart1) from table; + TODO - What happens if the query groups by the MIN/MAX field, and there is no other field as in: "select MY_MIN(a) from t1 group by a" ? @@ -13680,11 +14044,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) cause= "not single_table"; else if (join->select_lex->olap == ROLLUP_TYPE) /* Check (B3) for ROLLUP */ cause= "rollup"; - else if (table->s->keys == 0) /* There are no indexes to use. */ + else if (table->s->keys == 0) // There are no indexes to use. cause= "no index"; else if (join->conds && join->conds->used_tables() - & OUTER_REF_TABLE_BIT) /* Cannot execute with correlated conditions. */ + & OUTER_REF_TABLE_BIT) // Cannot execute with correlated conditions. cause= "correlated conditions"; + else if (table->stat_records() == 0) + cause= "Empty table"; // Exit now, records=0 messes up cost computations if (cause) { @@ -13698,7 +14064,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) (!join->select_distinct) && !is_agg_distinct) { - trace_group.add("chosen", false).add("cause","no group by or distinct"); + if (unlikely(trace_group.trace_started())) + trace_group.add("chosen", false).add("cause","no group by or distinct"); DBUG_RETURN(NULL); } /* Analyze the query in more detail. */ @@ -13723,8 +14090,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) continue; else { - trace_group.add("chosen", false) - .add("cause", "not applicable aggregate function"); + if (unlikely(trace_group.trace_started())) + trace_group. + add("chosen", false). + add("cause", "not applicable aggregate function"); DBUG_RETURN(NULL); } @@ -13736,15 +14105,19 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) min_max_arg_item= (Item_field*) expr; else if (! min_max_arg_item->eq(expr, 1)) { - trace_group.add("chosen", false) - .add("cause", "arguments different in min max function"); + if (unlikely(trace_group.trace_started())) + trace_group. + add("chosen", false). + add("cause", "arguments different in min max function"); DBUG_RETURN(NULL); } } else { - trace_group.add("chosen", false) - .add("cause", "no field item in min max function"); + if (unlikely(trace_group.trace_started())) + trace_group. + add("chosen", false). + add("cause", "no field item in min max function"); DBUG_RETURN(NULL); } } @@ -13753,8 +14126,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) /* Check (SA7). */ if (is_agg_distinct && (have_max || have_min)) { - trace_group.add("chosen", false) - .add("cause", "have both agg distinct and min max"); + if (unlikely(trace_group.trace_started())) + trace_group. + add("chosen", false). + add("cause", "have both agg distinct and min max"); DBUG_RETURN(NULL); } @@ -13766,8 +14141,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) { if (item->real_item()->type() != Item::FIELD_ITEM) { - trace_group.add("chosen", false) - .add("cause", "distinct field is expression"); + if (unlikely(trace_group.trace_started())) + trace_group. + add("chosen", false). + add("cause", "distinct field is expression"); DBUG_RETURN(NULL); } } @@ -13779,8 +14156,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) { if ((*tmp_group->item)->real_item()->type() != Item::FIELD_ITEM) { - trace_group.add("chosen", false) - .add("cause", "group field is expression"); + if (unlikely(trace_group.trace_started())) + trace_group. + add("chosen", false). + add("cause", "group field is expression"); DBUG_RETURN(NULL); } elements_in_group++; @@ -13875,7 +14254,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) does not qualify as covering in our case. If this is the case, below we check that all query fields are indeed covered by 'cur_index'. */ - if (cur_index_info->user_defined_key_parts == table->actual_n_key_parts(cur_index_info) + if (cur_index_info->user_defined_key_parts == + table->actual_n_key_parts(cur_index_info) && pk < MAX_KEY && cur_index != pk && (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX)) { @@ -13918,7 +14298,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) first Item? If so, then why? What is the array for? */ /* Above we already checked that all group items are fields. */ - DBUG_ASSERT((*tmp_group->item)->real_item()->type() == Item::FIELD_ITEM); + DBUG_ASSERT((*tmp_group->item)->real_item()->type() == + Item::FIELD_ITEM); Item_field *group_field= (Item_field *) (*tmp_group->item)->real_item(); if (group_field->field->eq(cur_part->field)) { @@ -14206,8 +14587,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) Field::itMBR : Field::itRAW, &has_min_max_fld, &has_other_fld)) { - trace_group.add("usable", false) - .add("cause", "unsupported predicate on agg attribute"); + if (unlikely(trace_group.trace_started())) + trace_group. + add("usable", false). + add("cause", "unsupported predicate on agg attribute"); DBUG_RETURN(NULL); } @@ -14216,8 +14599,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) */ if (is_agg_distinct && table->file->is_clustering_key(index)) { - trace_group.add("usable", false) - .add("cause", "index is clustered"); + if (unlikely(trace_group.trace_started())) + trace_group. + add("usable", false). + add("cause", "index is clustered"); DBUG_RETURN(NULL); } @@ -14238,11 +14623,31 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) read_plan->read_cost= best_read_cost; read_plan->records= best_records; - if (read_time < best_read_cost && is_agg_distinct) + if (is_agg_distinct) { - trace_group.add("index_scan", true); - read_plan->read_cost= 0; - read_plan->use_index_scan(); + double best_cost, duplicate_removal_cost; + ulonglong records; + handler *file= table->file; + + /* Calculate cost of distinct scan on index */ + if (best_index_tree && read_plan->quick_prefix_records) + records= read_plan->quick_prefix_records; + else + records= table->stat_records(); + + best_cost= file->cost(file->ha_key_scan_time(index, records)); + /* We only have 'best_records' left after duplication elimination */ + best_cost+= best_records * WHERE_COST_THD(thd); + duplicate_removal_cost= (DUPLICATE_REMOVAL_COST * records); + + if (best_cost < read_plan->read_cost + duplicate_removal_cost) + { + read_plan->read_cost= best_cost; + read_plan->use_index_scan(); + trace_group. + add("scan_cost", best_cost). + add("index_scan", true); + } } DBUG_PRINT("info", @@ -14713,13 +15118,42 @@ get_field_keypart(KEY *index, Field *field) have_min [in] True if there is a MIN function have_max [in] True if there is a MAX function read_cost [out] The cost to retrieve rows via this quick select - records [out] The number of rows retrieved + out_records [out] The number of rows retrieved DESCRIPTION This method computes the access cost of a TRP_GROUP_MIN_MAX instance and the number of rows returned. + The used algorithm used for finding the rows is: + + For each range (if no ranges, the range is the whole table) + Do an index search for the start of the range + As long as the found key is withing the range + If the found row matches the where clause, use the row otherwise skip it + Scan index for next group, jumping over all identical keys, done in + QUICK_GROUP_MIN_MAX_SELECT::next_prefix + If the engine does not support a native next_prefix, we will + either scan the index for the next value or do a new index dive + with 'find next bigger key'. + + When using MIN() and MAX() in the query, the calls to the storage engine + are as follows for each group: + Assuming kp1 in ('abc','def','ghi)' and kp2 between 1000 and 2000 + + read_key('abc', HA_READ_KEY_OR_NEXT) + In case of MIN() we do: + read_key('abc,:'1000', HA_READ_KEY_OR_NEXT) + In case of MAX() we do + read_key('abc,:'2000', HA_READ_PREFIX_LAST_OR_PREV) + In the following code we will assume that the MIN key will be in + the same block as the first key read. + (We should try to optimize away the extra call for MAX() at some + point). + NOTES + See get_best_group_min_max() for which kind of queries this function + will be called. + The cost computation distinguishes several cases: 1) No equality predicates over non-group attributes (thus no key_infix). If groups are bigger than blocks on the average, then we assume that it @@ -14761,104 +15195,108 @@ void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts, uint group_key_parts, SEL_TREE *range_tree, SEL_ARG *index_tree, ha_rows quick_prefix_records, bool have_min, bool have_max, - double *read_cost, ha_rows *records) + double *read_cost, ha_rows *out_records) { - ha_rows table_records; + uint key_length; + ha_rows records; ha_rows num_groups; ha_rows num_blocks; - uint keys_per_block; ha_rows keys_per_group; - ha_rows keys_per_subgroup; /* Average number of keys in sub-groups */ - /* formed by a key infix. */ - double p_overlap; /* Probability that a sub-group overlaps two blocks. */ double quick_prefix_selectivity; - double io_cost; + ulonglong io_cost; + handler *file= table->file; DBUG_ENTER("cost_group_min_max"); - table_records= table->stat_records(); - /* Assume block is 75 % full */ - keys_per_block= (uint) (table->file->stats.block_size * 3 / 4 / - (index_info->key_length + table->file->ref_length) - + 1); - num_blocks= (ha_rows)(table_records / keys_per_block) + 1; + /* Same code as in handler::key_read_time() */ + records= table->stat_records(); + key_length= (index_info->key_length + file->ref_length); /* Compute the number of keys in a group. */ if (!group_key_parts) { /* Summary over the whole table */ - keys_per_group= table_records; + keys_per_group= MY_MAX(records,1); } else { keys_per_group= (ha_rows) index_info->actual_rec_per_key(group_key_parts - 1); + if (keys_per_group == 0) /* If there is no statistics try to guess */ + { + /* each group contains 10% of all records */ + keys_per_group= (records / 10) + 1; + } } - - if (keys_per_group == 0) /* If there is no statistics try to guess */ - /* each group contains 10% of all records */ - keys_per_group= (table_records / 10) + 1; - num_groups= (table_records / keys_per_group) + 1; + if (keys_per_group > 1) + num_groups= (records / keys_per_group) + 1; + else + num_groups= records; /* Apply the selectivity of the quick select for group prefixes. */ if (range_tree && (quick_prefix_records != HA_POS_ERROR)) { + int groups; quick_prefix_selectivity= (double) quick_prefix_records / - (double) table_records; + (double) records; num_groups= (ha_rows) rint(num_groups * quick_prefix_selectivity); - set_if_bigger(num_groups, 1); - } + records= quick_prefix_records; - if (used_key_parts > group_key_parts) - { /* - Compute the probability that two ends of a subgroup are inside - different blocks. + /* + Try to handle cases like + WHERE a in (1,2,3) GROUP BY a + + If all ranges are eq_ranges for the group_key_parts we can use + this as the number of groups. */ - keys_per_subgroup= (ha_rows) index_info->actual_rec_per_key(used_key_parts - 1); - if (keys_per_subgroup >= keys_per_block) /* If a subgroup is bigger than */ - p_overlap= 1.0; /* a block, it will overlap at least two blocks. */ + groups= index_tree->number_of_eq_groups(group_key_parts); + if (groups > 0) + num_groups= groups; else { - double blocks_per_group= (double) num_blocks / (double) num_groups; - p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group; - p_overlap= MY_MIN(p_overlap, 1.0); + /* + Expect at least as many groups as there is ranges in the index + + This is mostly relevant for queries with few records, which is + something we have a lot of in our test suites. + In theory it is possible to scan the index_tree and for cases + where all ranges are eq ranges, we could calculate the exact number + of groups. This is probably an overkill so for now we estimate + the lower level of number of groups by the range elements in the + tree. + */ + set_if_bigger(num_groups, MY_MAX(index_tree->elements, 1)); } - io_cost= (double) MY_MIN(num_groups * (1 + p_overlap), num_blocks); + /* There cannot be more groups than matched records */ + set_if_smaller(num_groups, quick_prefix_records); } - else - io_cost= (keys_per_group > keys_per_block) ? - (have_min && have_max) ? (double) (num_groups + 1) : - (double) num_groups : - (double) num_blocks; + DBUG_ASSERT(num_groups <= records); + + /* Calculate the number of blocks we will touch for the table or range scan */ + num_blocks= (records * key_length / INDEX_BLOCK_FILL_FACTOR_DIV * + INDEX_BLOCK_FILL_FACTOR_MUL) / file->stats.block_size + 1; + + io_cost= (have_max) ? num_groups * 2 : num_groups; + set_if_smaller(io_cost, num_blocks); /* CPU cost must be comparable to that of an index scan as computed in SQL_SELECT::test_quick_select(). When the groups are small, e.g. for a unique index, using index scan will be cheaper since it reads the next record without having to re-position to it on every - group. To make the CPU cost reflect this, we estimate the CPU cost - as the sum of: - 1. Cost for evaluating the condition (similarly as for index scan). - 2. Cost for navigating the index structure (assuming a b-tree). - Note: We only add the cost for one comparision per block. For a - b-tree the number of comparisons will be larger. - TODO: This cost should be provided by the storage engine. + group. */ - const double tree_traversal_cost= - ceil(log(static_cast(table_records))/ - log(static_cast(keys_per_block))) * - 1/(2*TIME_FOR_COMPARE); - - const double cpu_cost= num_groups * - (tree_traversal_cost + 1/TIME_FOR_COMPARE_IDX); - - *read_cost= io_cost + cpu_cost; - *records= num_groups; + uint keyno= (uint) (index_info - table->key_info); + *read_cost= file->cost(file->ha_keyread_and_compare_time(keyno, + (ulong) num_groups, + num_groups, + io_cost)); + *out_records= num_groups; DBUG_PRINT("info", - ("table rows: %lu keys/block: %u keys/group: %lu " + ("rows: %lu keys/group: %lu " "result rows: %lu blocks: %lu", - (ulong) table_records, keys_per_block, (ulong) keys_per_group, - (ulong) *records, (ulong) num_blocks)); + (ulong) records, (ulong) keys_per_group, + (ulong) *out_records, (ulong) num_blocks)); DBUG_VOID_RETURN; } @@ -14898,7 +15336,8 @@ TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows, group_prefix_len, group_key_parts, used_key_parts, index_info, index, read_cost, records, key_infix_len, - key_infix, parent_alloc, is_index_scan); + key_infix, parent_alloc, + is_index_scan); if (!quick) DBUG_RETURN(NULL); diff --git a/sql/opt_range.h b/sql/opt_range.h index 7a067b49295..91cbfb3412b 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -302,6 +302,7 @@ class SEL_ARG :public Sql_alloc { static int sel_cmp(Field *field, uchar *a, uchar *b, uint8 a_flag, uint8 b_flag); + bool min_max_are_equal() const; public: uint8 min_flag,max_flag,maybe_flag; uint8 part; // Which key part @@ -401,6 +402,7 @@ public: return false; return true; } + int number_of_eq_groups(uint group_key_parts) const; inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; } inline void maybe_smaller() { maybe_flag=1; } /* Return true iff it's a single-point null interval */ @@ -1109,6 +1111,13 @@ public: */ uint used_key_parts; + /* + Set to 1 if we used group by optimization to calculate number of rows + in the result, stored in table->opt_range_condition_rows. + This is only used for asserts. + */ + bool group_by_optimization_used; + QUICK_SELECT_I(); virtual ~QUICK_SELECT_I(){}; diff --git a/sql/opt_split.cc b/sql/opt_split.cc index 86ed442814c..99082813d7f 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -188,6 +188,7 @@ #include "mariadb.h" #include "sql_select.h" #include "opt_trace.h" +#include "optimizer_defaults.h" /* Info on a splitting field */ struct SplM_field_info @@ -245,10 +246,10 @@ public: List plan_cache; /* Cost of best execution plan for join when nothing is pushed */ double unsplit_cost; + /* Split operation cost (result form spl_postjoin_oper_cost()) */ + double unsplit_oper_cost; /* Cardinality of T when nothing is pushed */ double unsplit_card; - /* Lastly evaluated execution plan for 'join' with pushed equalities */ - SplM_plan_info *last_plan; SplM_plan_info *find_plan(TABLE *table, uint key, uint parts); }; @@ -665,20 +666,28 @@ add_ext_keyuses_for_splitting_field(Dynamic_array *ext_keyuses, /* @brief Cost of the post join operation used in specification of splittable table + This does not include the cost of creating the temporary table as this + operation can be executed many times for the same temporary table. */ static double spl_postjoin_oper_cost(THD *thd, double join_record_count, uint rec_len) { double cost; - cost= get_tmp_table_write_cost(thd, join_record_count,rec_len) * - join_record_count; // cost to fill tmp table - cost+= get_tmp_table_lookup_cost(thd, join_record_count,rec_len) * - join_record_count; // cost to perform post join operation used here - cost+= get_tmp_table_lookup_cost(thd, join_record_count, rec_len) + - (join_record_count == 0 ? 0 : - join_record_count * log2 (join_record_count)) * - SORT_INDEX_CMP_COST; // cost to perform sorting + TMPTABLE_COSTS tmp_cost= get_tmp_table_costs(thd, join_record_count, + rec_len, 0, 1); + /* cost to fill tmp table */ + cost= tmp_cost.write * join_record_count; + /* cost to perform post join operation used here */ + cost+= tmp_cost.lookup * join_record_count; + /* cost to preform sorting */ + /* QQQ + We should use cost_of_filesort() for computing sort. + Do we always preform sorting ? If not, this should be done conditionally + */ + cost+= ((join_record_count == 0 ? 0 : + join_record_count * log2 (join_record_count)) * + SORT_INDEX_CMP_COST); return cost; } @@ -710,7 +719,6 @@ void JOIN::add_keyuses_for_splitting() size_t idx; KEYUSE_EXT *keyuse_ext; KEYUSE_EXT keyuse_ext_end; - double oper_cost; uint rec_len; uint added_keyuse_count; TABLE *table= select_lex->master_unit()->derived->table; @@ -737,10 +745,11 @@ void JOIN::add_keyuses_for_splitting() rec_len= table->s->rec_buff_length; - oper_cost= spl_postjoin_oper_cost(thd, join_record_count, rec_len); - - spl_opt_info->unsplit_cost= best_positions[table_count-1].read_time + - oper_cost; + spl_opt_info->unsplit_oper_cost= spl_postjoin_oper_cost(thd, + join_record_count, + rec_len); + spl_opt_info->unsplit_cost= (best_positions[table_count-1].read_time + + spl_opt_info->unsplit_oper_cost); if (!(save_qep= new Join_plan_state(table_count + 1))) goto err; @@ -872,7 +881,7 @@ void reset_validity_vars_for_keyuses(KEYUSE_EXT *key_keyuse_ext_start, splitting the function set it as the true plan of materialization of the table T. The function caches the found plans for materialization of table T - together if the info what key was used for splitting. Next time when + together with the info what key was used for splitting. Next time when the optimizer prefers to use the same key the plan is taken from the cache of plans @@ -897,6 +906,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, SplM_plan_info *spl_plan= 0; uint best_key= 0; uint best_key_parts= 0; + bool chosen, already_printed; /* Check whether there are keys that can be used to join T employing splitting @@ -954,7 +964,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, } while (keyuse_ext->table == table); } - spl_opt_info->last_plan= 0; + chosen= 0; if (best_table) { /* @@ -972,7 +982,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, table_map all_table_map= (((table_map) 1) << join->table_count) - 1; reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table, best_key, remaining_tables, true); - choose_plan(join, all_table_map & ~join->const_table_map); + choose_plan(join, all_table_map & ~join->const_table_map, 0); /* Check that the chosen plan is really a splitting plan. @@ -1003,57 +1013,74 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, spl_opt_info->unsplit_card : 1); uint rec_len= table->s->rec_buff_length; - double split_card= spl_opt_info->unsplit_card * spl_plan->split_sel; - double oper_cost= split_card * - spl_postjoin_oper_cost(thd, split_card, rec_len); - spl_plan->cost= join->best_positions[join->table_count-1].read_time + - + oper_cost; + double oper_cost= (split_card * + spl_postjoin_oper_cost(thd, split_card, rec_len)); + spl_plan->cost= (join->best_positions[join->table_count-1].read_time + + oper_cost); + + chosen= (record_count * spl_plan->cost + COST_EPS < + spl_opt_info->unsplit_cost); if (unlikely(thd->trace_started())) { Json_writer_object wrapper(thd); - Json_writer_object find_trace(thd, "best_splitting"); - find_trace.add("table", best_table->alias.c_ptr()); - find_trace.add("key", best_table->key_info[best_key].name); - find_trace.add("record_count", record_count); - find_trace.add("cost", spl_plan->cost); - find_trace.add("unsplit_cost", spl_opt_info->unsplit_cost); + Json_writer_object find_trace(thd, "split_materialized"); + find_trace. + add("table", best_table->alias.c_ptr()). + add("key", best_table->key_info[best_key].name). + add("org_cost",join->best_positions[join->table_count-1].read_time). + add("postjoin_cost", oper_cost). + add("one_splitting_cost", spl_plan->cost). + add("unsplit_postjoin_cost", spl_opt_info->unsplit_oper_cost). + add("unsplit_cost", spl_opt_info->unsplit_cost). + add("rows", split_card). + add("outer_rows", record_count). + add("total_splitting_cost", record_count * spl_plan->cost). + add("chosen", chosen); } memcpy((char *) spl_plan->best_positions, (char *) join->best_positions, sizeof(POSITION) * join->table_count); reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table, best_key, remaining_tables, false); + already_printed= 1; } - if (spl_plan) + else { - if(record_count * spl_plan->cost < spl_opt_info->unsplit_cost - 0.01) - { - /* - The best plan that employs splitting is cheaper than - the plan without splitting - */ - spl_opt_info->last_plan= spl_plan; - } + chosen= (record_count * spl_plan->cost + COST_EPS < + spl_opt_info->unsplit_cost); + already_printed= 0; } } /* Set the cost of the preferred materialization for this partial join */ - records= (ha_rows)spl_opt_info->unsplit_card; - spl_plan= spl_opt_info->last_plan; - if (spl_plan) + if (chosen) { - startup_cost= record_count * spl_plan->cost; - records= (ha_rows) (records * spl_plan->split_sel); + /* + The best plan that employs splitting is cheaper than + the plan without splitting + */ - Json_writer_object trace(thd, "lateral_derived"); - trace.add("startup_cost", startup_cost); - trace.add("splitting_cost", spl_plan->cost); - trace.add("records", records); + startup_cost= record_count * spl_plan->cost; + records= (ha_rows) (spl_opt_info->unsplit_card * spl_plan->split_sel); + + if (unlikely(thd->trace_started()) && ! already_printed) + { + Json_writer_object trace(thd, "split_materialized"); + trace. + add("one_splitting_cost", spl_plan->cost). + add("total_splitting_cost", startup_cost). + add("rows", records); + } } else - startup_cost= spl_opt_info->unsplit_cost; + { + /* Restore original values */ + startup_cost= spl_opt_info->unsplit_cost; + records= (ha_rows) spl_opt_info->unsplit_card; + spl_plan= 0; + } return spl_plan; } diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 3e2531b90cd..655ffebab65 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -35,6 +35,7 @@ #include "sql_test.h" #include #include "opt_trace.h" +#include "optimizer_defaults.h" /* This file contains optimizations for semi-join subqueries. @@ -448,7 +449,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred); static bool convert_subq_to_jtbm(JOIN *parent_join, Item_in_subselect *subq_pred, bool *remove); static TABLE_LIST *alloc_join_nest(THD *thd); -static uint get_tmp_table_rec_length(Ref_ptr_array p_list, uint elements); +static uint get_tmp_table_rec_length(Ref_ptr_array p_list, uint elements, + bool *blobs_used); bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables); static SJ_MATERIALIZATION_INFO * at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab, @@ -664,17 +666,6 @@ int check_and_do_in_subquery_rewrites(JOIN *join) DBUG_RETURN(-1); } } - /* Check if any table is not supporting comparable rowids */ - { - List_iterator_fast li(select_lex->outer_select()->leaf_tables); - TABLE_LIST *tbl; - while ((tbl = li++)) - { - TABLE *table= tbl->table; - if (table && table->file->ha_table_flags() & HA_NON_COMPARABLE_ROWID) - join->not_usable_rowid_map|= table->map; - } - } DBUG_PRINT("info", ("Checking if subq can be converted to semi-join")); /* @@ -696,9 +687,10 @@ int check_and_do_in_subquery_rewrites(JOIN *join) 11. It is first optimisation (the subquery could be moved from ON clause during first optimisation and then be considered for SJ on the second when it is too late) - 12. All tables supports comparable rowids. - This is needed for DuplicateWeedout strategy to work (which - is the catch-all semi-join strategy so it must be applicable). + + There are also other requirements which cannot be checked at this phase, + yet. They are checked later in convert_join_subqueries_to_semijoins(), + look for calls to block_conversion_to_sj(). */ if (optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN) && in_subs && // 1 @@ -713,8 +705,7 @@ int check_and_do_in_subquery_rewrites(JOIN *join) !((join->select_options | // 10 select_lex->outer_select()->join->select_options) // 10 & SELECT_STRAIGHT_JOIN) && // 10 - select_lex->first_cond_optimization && // 11 - join->not_usable_rowid_map == 0) // 12 + select_lex->first_cond_optimization) // 11 { DBUG_PRINT("info", ("Subquery is semi-join conversion candidate")); @@ -910,8 +901,10 @@ bool subquery_types_allow_materialization(THD* thd, Item_in_subselect *in_subs) outer, converted_from_in_predicate)) { - trace_transform.add("possible", false); - trace_transform.add("cause", "types mismatch"); + if (unlikely(trace_transform.trace_started())) + trace_transform. + add("possible", false). + add("cause", "types mismatch"); DBUG_RETURN(FALSE); } } @@ -933,8 +926,10 @@ bool subquery_types_allow_materialization(THD* thd, Item_in_subselect *in_subs) { in_subs->types_allow_materialization= TRUE; in_subs->sjm_scan_allowed= all_are_fields; - trace_transform.add("sjm_scan_allowed", all_are_fields) - .add("possible", true); + if (unlikely(trace_transform.trace_started())) + trace_transform. + add("sjm_scan_allowed", all_are_fields). + add("possible", true); DBUG_PRINT("info",("subquery_types_allow_materialization: ok, allowed")); DBUG_RETURN(TRUE); } @@ -1224,7 +1219,36 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) } } - if (join->select_options & SELECT_STRAIGHT_JOIN) + /* + Compute join->not_usable_rowid_map. + The idea is: + - DuplicateWeedout strategy requires that one is able to get the rowid + (call h->position()) for tables in the parent select. Obtained Rowid + values must be stable across table scans. + = Rowids are typically available. The only known exception is federatedx + tables. + - The optimizer requires that DuplicateWeedout strategy is always + applicable. It is the only strategy that is applicable for any join + order. The optimizer is not prepared for the situation where it has + constructed a join order and then it turns out that there's no semi-join + strategy that can be used for it. + + Because of the above, we will not use semi-joins if the parent select has + tables which do not support rowids. + */ + { + List_iterator_fast li(join->select_lex->leaf_tables); + TABLE_LIST *tbl; + while ((tbl = li++)) + { + TABLE *table= tbl->table; + if (table && table->file->ha_table_flags() & HA_NON_COMPARABLE_ROWID) + join->not_usable_rowid_map|= table->map; + } + } + + if (join->select_options & SELECT_STRAIGHT_JOIN || + join->not_usable_rowid_map != 0) { /* Block conversion to semijoins for all candidates */ li.rewind(); @@ -1294,8 +1318,10 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) OPT_TRACE_TRANSFORM(thd, trace_wrapper, trace_transform, in_subq->get_select_lex()->select_number, "IN (SELECT)", "semijoin"); - trace_transform.add("converted_to_semi_join", false) - .add("cause", "subquery attached to the ON clause"); + if (unlikely(trace_transform.trace_started())) + trace_transform. + add("converted_to_semi_join", false). + add("cause", "subquery attached to the ON clause"); break; } @@ -1307,9 +1333,10 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) if (join->table_count + in_subq->unit->first_select()->join->table_count >= MAX_TABLES) { - trace_transform.add("converted_to_semi_join", false); - trace_transform.add("cause", - "table in parent join now exceeds MAX_TABLES"); + if (unlikely(trace_transform.trace_started())) + trace_transform. + add("converted_to_semi_join", false). + add("cause", "table in parent join now exceeds MAX_TABLES"); break; } if (convert_subq_to_sj(join, in_subq)) @@ -1441,6 +1468,7 @@ void get_delayed_table_estimates(TABLE *table, Item_in_subselect *item= table->pos_in_table_list->jtbm_subselect; Table_function_json_table *table_function= table->pos_in_table_list->table_function; + handler *file= table->file; if (table_function) { @@ -1460,9 +1488,11 @@ void get_delayed_table_estimates(TABLE *table, /* Calculate cost of scanning the temptable */ double data_size= COST_MULT(item->jtbm_record_count, hash_sj_engine->tmp_table->s->reclength); - /* Do like in handler::scan_time() */ - *scan_time= ((data_size/table->file->stats.block_size+2) * - table->file->avg_io_cost()); + + /* Do like in handler::ha_scan_and_compare_time, but ignore the where cost */ + *scan_time= ((data_size/IO_SIZE * table->file->DISK_READ_COST * + table->file->DISK_READ_RATIO) + + *out_rows * file->ROW_COPY_COST); } @@ -2490,8 +2520,7 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map) !sj_nest->sj_subq_pred->is_correlated && sj_nest->sj_subq_pred->types_allow_materialization) { - join->emb_sjm_nest= sj_nest; - if (choose_plan(join, all_table_map &~join->const_table_map)) + if (choose_plan(join, all_table_map &~join->const_table_map, sj_nest)) DBUG_RETURN(TRUE); /* purecov: inspected */ /* The best plan to run the subquery is now in join->best_positions, @@ -2507,24 +2536,13 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map) sjm->is_used= FALSE; double subjoin_out_rows, subjoin_read_time; - /* - join->get_partial_cost_and_fanout(n_tables + join->const_tables, - table_map(-1), - &subjoin_read_time, - &subjoin_out_rows); - */ - join->get_prefix_cost_and_fanout(n_tables, + join->get_prefix_cost_and_fanout(n_tables, &subjoin_read_time, &subjoin_out_rows); - sjm->materialization_cost.convert_from_cost(subjoin_read_time); + sjm->materialization_cost=subjoin_read_time; sjm->rows_with_duplicates= sjm->rows= subjoin_out_rows; - // Don't use the following list because it has "stale" items. use - // ref_pointer_array instead: - // - //List &right_expr_list= - // sj_nest->sj_subq_pred->unit->first_select()->item_list; /* Adjust output cardinality estimates. If the subquery has form @@ -2557,8 +2575,12 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map) int tableno; double rows= 1.0; while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END) - rows= COST_MULT(rows, - join->map2table[tableno]->table->opt_range_condition_rows); + { + ha_rows tbl_rows=join->map2table[tableno]-> + table->opt_range_condition_rows; + + rows= COST_MULT(rows, rows2double(tbl_rows)); + } sjm->rows= MY_MIN(sjm->rows, rows); } memcpy((uchar*) sjm->positions, @@ -2568,33 +2590,43 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map) /* Calculate temporary table parameters and usage costs */ + bool blobs_used; uint rowlen= get_tmp_table_rec_length(subq_select->ref_pointer_array, - subq_select->item_list.elements); - double lookup_cost= get_tmp_table_lookup_cost(join->thd, - subjoin_out_rows, rowlen); - double write_cost= get_tmp_table_write_cost(join->thd, - subjoin_out_rows, rowlen); + subq_select->item_list.elements, + &blobs_used); + TMPTABLE_COSTS cost= get_tmp_table_costs(join->thd, + subjoin_out_rows, rowlen, + blobs_used, 1); + double scan_cost, total_cost; + double row_copy_cost= ROW_COPY_COST_THD(thd); /* Let materialization cost include the cost to write the data into the - temporary table: + temporary table. Note that smj->materialization_cost already includes + row copy and compare costs of finding the original row. */ - sjm->materialization_cost.add_io(subjoin_out_rows, write_cost); - + sjm->materialization_cost+=subjoin_out_rows * cost.write + cost.create; + /* Set the cost to do a full scan of the temptable (will need this to - consider doing sjm-scan): - */ - sjm->scan_cost.reset(); - sjm->scan_cost.add_io(sjm->rows, lookup_cost); + consider doing sjm-scan). See ha_scan_time() for the basics of + the calculations. + We don't need to check the where clause for each row, so no + WHERE_COST is needed. + */ + scan_cost= (rowlen * (double) sjm->rows) / cost.block_size; + total_cost= (scan_cost * cost.cache_hit_ratio * cost.avg_io_cost + + TABLE_SCAN_SETUP_COST_THD(thd) + + row_copy_cost * sjm->rows); + sjm->scan_cost=total_cost; - sjm->lookup_cost.convert_from_cost(lookup_cost); + /* When reading a row, we have also to check the where clause */ + sjm->lookup_cost= cost.lookup + WHERE_COST_THD(thd); sj_nest->sj_mat_info= sjm; DBUG_EXECUTE("opt", print_sjm(sjm);); } } } - join->emb_sjm_nest= NULL; DBUG_RETURN(FALSE); } @@ -2616,11 +2648,13 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map) Length of the temptable record, in bytes */ -static uint get_tmp_table_rec_length(Ref_ptr_array p_items, uint elements) +static uint get_tmp_table_rec_length(Ref_ptr_array p_items, uint elements, + bool *blobs_used) { uint len= 0; Item *item; - //List_iterator it(items); + + *blobs_used= 0; for (uint i= 0; i < elements ; i++) { item = p_items[i]; @@ -2643,6 +2677,8 @@ static uint get_tmp_table_rec_length(Ref_ptr_array p_items, uint elements) len += 8; else len += item->max_length; + if (item->max_length > MAX_FIELD_VARCHARLENGTH) + *blobs_used= 1; break; case DECIMAL_RESULT: len += 10; @@ -2658,46 +2694,62 @@ static uint get_tmp_table_rec_length(Ref_ptr_array p_items, uint elements) /** - The cost of a lookup into a unique hash/btree index on a temporary table - with 'row_count' rows each of size 'row_size'. + The cost of a create, write and read into a unique hash/btree index on + a temporary table with 'row_count' rows each of size 'row_size'. @param thd current query context @param row_count number of rows in the temp table @param row_size average size in bytes of the rows - @return the cost of one lookup + @return The cost of using the temporary table + + TODO: + This is an optimistic estimate. We are not taking into account: + - That we first write into a memory and then overflow to disk. + - If binary trees would be used for heap tables. + - The addition cost of writing a row to memory/disk and possible + index reorganization. */ -double -get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size) +TMPTABLE_COSTS +get_tmp_table_costs(THD *thd, double row_count, uint row_size, bool blobs_used, + bool add_copy_cost) { - if (row_count > thd->variables.max_heap_table_size / (double) row_size) - return (double) DISK_TEMPTABLE_LOOKUP_COST; + TMPTABLE_COSTS cost; + /* From heap_prepare_hp_create_info(), assuming one hash key used */ + row_size+= sizeof(char*)*2; + row_size= MY_ALIGN(MY_MAX(row_size, sizeof(char*)) + 1, sizeof(char*)); + + if (row_count > thd->variables.max_heap_table_size / (double) row_size || + blobs_used) + { + double row_copy_cost= (add_copy_cost ? + tmp_table_optimizer_costs.row_copy_cost : + 0); + /* Disk based table */ + cost.lookup= ((tmp_table_optimizer_costs.key_lookup_cost * + tmp_table_optimizer_costs.disk_read_ratio) + + row_copy_cost); + cost.write= cost.lookup; + cost.create= DISK_TEMPTABLE_CREATE_COST; + cost.block_size= DISK_TEMPTABLE_BLOCK_SIZE; + cost.avg_io_cost= tmp_table_optimizer_costs.disk_read_cost; + cost.cache_hit_ratio= tmp_table_optimizer_costs.disk_read_ratio; + } else - return (double) HEAP_TEMPTABLE_LOOKUP_COST; -} - -/** - The cost of writing a row into a temporary table with 'row_count' unique - rows each of size 'row_size'. - - @param thd current query context - @param row_count number of rows in the temp table - @param row_size average size in bytes of the rows - - @return the cost of writing one row -*/ - -double -get_tmp_table_write_cost(THD *thd, double row_count, uint row_size) -{ - double lookup_cost= get_tmp_table_lookup_cost(thd, row_count, row_size); - /* - TODO: - This is an optimistic estimate. Add additional costs resulting from - actually writing the row to memory/disk and possible index reorganization. - */ - return lookup_cost; + { + /* Values are as they are in heap.h */ + double row_copy_cost= (add_copy_cost ? + heap_optimizer_costs.row_copy_cost : + 0); + cost.lookup= HEAP_TEMPTABLE_LOOKUP_COST + row_copy_cost; + cost.write= cost.lookup; + cost.create= HEAP_TEMPTABLE_CREATE_COST; + cost.block_size= 1; + cost.avg_io_cost= 0; + cost.cache_hit_ratio= 0; + } + return cost; } @@ -2942,9 +2994,16 @@ void optimize_semi_joins(JOIN *join, table_map remaining_tables, uint idx, 2. using strategy Z is cheaper, but it only removes fanout from semijoin X. 3. We have no clue what to do about fanount of semi-join Y. + + For the first iteration read_time will always be bigger than + *current_read_time (as the 'strategy' is an addition to the + chosen plan) . If a strategy was picked + (dusp_producing_tables & handled_fanout is true), then + *current_read_time is updated and the cost for the next + strategy can be smaller than *current_read_time. */ if ((dups_producing_tables & handled_fanout) || - (read_time < *current_read_time && + (read_time + COST_EPS < *current_read_time && !(handled_fanout & pos->inner_tables_handled_with_other_sjs))) { DBUG_ASSERT(pos->sj_strategy != sj_strategy); @@ -3142,9 +3201,9 @@ bool Sj_materialization_picker::check_qep(JOIN *join, mat_read_time= COST_ADD(prefix_cost, - COST_ADD(mat_info->materialization_cost.total_cost(), + COST_ADD(mat_info->materialization_cost, COST_MULT(prefix_rec_count, - mat_info->lookup_cost.total_cost()))); + mat_info->lookup_cost))); /* NOTE: When we pick to use SJM[-Scan] we don't memcpy its POSITION @@ -3158,8 +3217,9 @@ bool Sj_materialization_picker::check_qep(JOIN *join, *strategy= SJ_OPT_MATERIALIZE; if (unlikely(trace.trace_started())) { - trace.add("records", *record_count); - trace.add("read_time", *read_time); + trace. + add("rows", *record_count). + add("cost", *read_time); } return TRUE; } @@ -3193,9 +3253,9 @@ bool Sj_materialization_picker::check_qep(JOIN *join, /* Add materialization cost */ prefix_cost= COST_ADD(prefix_cost, - COST_ADD(mat_info->materialization_cost.total_cost(), + COST_ADD(mat_info->materialization_cost, COST_MULT(prefix_rec_count, - mat_info->scan_cost.total_cost()))); + mat_info->scan_cost))); prefix_rec_count= COST_MULT(prefix_rec_count, mat_info->rows); uint i; @@ -3212,10 +3272,8 @@ bool Sj_materialization_picker::check_qep(JOIN *join, best_access_path(join, join->positions[i].table, rem_tables, join->positions, i, disable_jbuf, prefix_rec_count, &curpos, &dummy); - prefix_rec_count= COST_MULT(prefix_rec_count, curpos.records_read); + prefix_rec_count= COST_MULT(prefix_rec_count, curpos.records_out); prefix_cost= COST_ADD(prefix_cost, curpos.read_time); - prefix_cost= COST_ADD(prefix_cost, - prefix_rec_count / TIME_FOR_COMPARE); //TODO: take into account join condition selectivity here } @@ -3240,8 +3298,9 @@ bool Sj_materialization_picker::check_qep(JOIN *join, *handled_fanout= mat_nest->sj_inner_tables; if (unlikely(trace.trace_started())) { - trace.add("records", *record_count); - trace.add("read_time", *read_time); + trace. + add("rows", *record_count). + add("cost", *read_time); } return TRUE; } @@ -3340,8 +3399,9 @@ bool LooseScan_picker::check_qep(JOIN *join, *handled_fanout= first->table->emb_sj_nest->sj_inner_tables; if (unlikely(trace.trace_started())) { - trace.add("records", *record_count); - trace.add("read_time", *read_time); + trace. + add("rows", *record_count). + add("cost", *read_time); } return TRUE; } @@ -3432,13 +3492,13 @@ bool Firstmatch_picker::check_qep(JOIN *join, optimizer_flag(join->thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE)) { /* - An important special case: only one inner table, and @@optimizer_switch - allows join buffering. + An important special case: only one inner table, and + @@optimizer_switch allows join buffering. - read_time is the same (i.e. FirstMatch doesn't add any cost - remove fanout added by the last table */ if (*record_count) - *record_count /= join->positions[idx].records_read; + *record_count /= join->positions[idx].records_out; } else { @@ -3458,8 +3518,9 @@ bool Firstmatch_picker::check_qep(JOIN *join, *strategy= SJ_OPT_FIRST_MATCH; if (unlikely(trace.trace_started())) { - trace.add("records", *record_count); - trace.add("read_time", *read_time); + trace. + add("rows", *record_count). + add("cost", *read_time); } return TRUE; } @@ -3471,6 +3532,56 @@ bool Firstmatch_picker::check_qep(JOIN *join, } +/* + Duplicate_weedout strategy is described at + https://mariadb.com/kb/en/duplicateweedout-strategy/ + + The idea is that if one has a subquery of type: + + select * + from Country + where + Country.code IN (select City.Country + from City + where + ...) + + Before semi join optimization it was executed this way: + - Scan rows in Country + - For each accepted row, execute the sub query with + 'Country.code = City.Country' added to the WHERE clause and with + LIMIT 1 + + With semi join optimization it can be converted to the following semi join. + + select * from Country semi-join City + where Country.code = City.Country and ... + + This is executed as: + + - Scan rows in Country + - Scan rows in City with 'Country.code = City.Country' added to the + subquery WHERE clause. Stop scanning after the first match. + + or + + - Create temporary table to store City.Country (with a unique key) + - Scan rows in City (according to plan for City) and put them into the + temporary table + - Scan the temporary table + - Do index lookup in Country table with City.Country + +With Duplicate_weedout we would try to instead do: + + - Create temporary table to hold unique rowid's for the Country + - Scan rows in City (according to plan for City) + - Scan rows in Country (according to plan for Country) + - Write Country.id rowid to temporary table. If there was no + conflicting row in the temporary table, accept the row combination. + - Delete temporary table +*/ + + void Duplicate_weedout_picker::set_from_prev(POSITION *prev) { if (prev->dups_weedout_picker.is_used) @@ -3535,46 +3646,42 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join, */ uint first_tab= first_dupsweedout_table; double dups_cost; - double prefix_rec_count; + double first_weedout_table_rec_count; double sj_inner_fanout= 1.0; double sj_outer_fanout= 1.0; uint temptable_rec_size; - Json_writer_object trace(join->thd); - trace.add("strategy", "DuplicateWeedout"); if (first_tab == join->const_tables) { - prefix_rec_count= 1.0; + first_weedout_table_rec_count= 1.0; temptable_rec_size= 0; dups_cost= 0.0; } else { dups_cost= join->positions[first_tab - 1].prefix_cost; - prefix_rec_count= join->positions[first_tab - 1].prefix_record_count; + first_weedout_table_rec_count= + join->positions[first_tab - 1].prefix_record_count; temptable_rec_size= 8; /* This is not true but we'll make it so */ } table_map dups_removed_fanout= 0; - double current_fanout= prefix_rec_count; for (uint j= first_dupsweedout_table; j <= idx; j++) { POSITION *p= join->positions + j; - current_fanout= COST_MULT(current_fanout, p->records_read); - dups_cost= COST_ADD(dups_cost, - COST_ADD(p->read_time, - current_fanout / TIME_FOR_COMPARE)); + dups_cost= COST_ADD(dups_cost, p->read_time); + if (p->table->emb_sj_nest) { - sj_inner_fanout= COST_MULT(sj_inner_fanout, p->records_read); + sj_inner_fanout= COST_MULT(sj_inner_fanout, p->records_out); dups_removed_fanout |= p->table->table->map; } else { + sj_outer_fanout= COST_MULT(sj_outer_fanout, p->records_out); /* Ensure that table supports comparable rowids */ DBUG_ASSERT(!(p->table->table->file->ha_table_flags() & HA_NON_COMPARABLE_ROWID)); - sj_outer_fanout= COST_MULT(sj_outer_fanout, p->records_read); temptable_rec_size += p->table->table->file->ref_length; } } @@ -3583,32 +3690,38 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join, Add the cost of temptable use. The table will have sj_outer_fanout records, and we will make - sj_outer_fanout table writes - - sj_inner_fanout*sj_outer_fanout lookups. + - sj_inner_fanout*sj_outer_fanout lookups. + There is no row copy cost (as we are only copying rowid) and no + compare cost (as we are only checking if the row exists by + checking if we got a write error. */ - double one_lookup_cost= get_tmp_table_lookup_cost(join->thd, - sj_outer_fanout, - temptable_rec_size); - double one_write_cost= get_tmp_table_write_cost(join->thd, - sj_outer_fanout, - temptable_rec_size); - - double write_cost= COST_MULT(join->positions[first_tab].prefix_record_count, - sj_outer_fanout * one_write_cost); - double full_lookup_cost= - COST_MULT(join->positions[first_tab].prefix_record_count, - COST_MULT(sj_outer_fanout, - sj_inner_fanout * one_lookup_cost)); - dups_cost= COST_ADD(dups_cost, COST_ADD(write_cost, full_lookup_cost)); + TMPTABLE_COSTS one_cost= get_tmp_table_costs(join->thd, + sj_outer_fanout, + temptable_rec_size, + 0, 0); + double write_cost= (one_cost.create + + first_weedout_table_rec_count * sj_outer_fanout * one_cost.write); + double full_lookup_cost= (first_weedout_table_rec_count* sj_outer_fanout * + sj_inner_fanout * one_cost.lookup); + *read_time= dups_cost + write_cost + full_lookup_cost; - *read_time= dups_cost; - *record_count= prefix_rec_count * sj_outer_fanout; + *record_count= first_weedout_table_rec_count * sj_outer_fanout; *handled_fanout= dups_removed_fanout; *strategy= SJ_OPT_DUPS_WEEDOUT; - if (unlikely(trace.trace_started())) + if (unlikely(join->thd->trace_started())) { - trace.add("records", *record_count); - trace.add("read_time", *read_time); + Json_writer_object trace(join->thd); + trace. + add("strategy", "DuplicateWeedout"). + add("prefix_row_count", first_weedout_table_rec_count). + add("tmp_table_rows", sj_outer_fanout). + add("sj_inner_fanout", sj_inner_fanout). + add("rows", *record_count). + add("dups_cost", dups_cost). + add("write_cost", write_cost). + add("full_lookup_cost", full_lookup_cost). + add("total_cost", *read_time); } return TRUE; } @@ -3657,33 +3770,37 @@ void JOIN::dbug_verify_sj_inner_tables(uint prefix_size) const */ void restore_prev_sj_state(const table_map remaining_tables, - const JOIN_TAB *tab, uint idx) + const JOIN_TAB *tab, uint idx) { TABLE_LIST *emb_sj_nest; - if (tab->emb_sj_nest) + if ((emb_sj_nest= tab->emb_sj_nest)) { - table_map subq_tables= tab->emb_sj_nest->sj_inner_tables; + table_map subq_tables= emb_sj_nest->sj_inner_tables; tab->join->sjm_lookup_tables &= ~subq_tables; - } - if (!tab->join->emb_sjm_nest && (emb_sj_nest= tab->emb_sj_nest)) - { - table_map subq_tables= emb_sj_nest->sj_inner_tables & - ~tab->join->const_table_map; - /* If we're removing the last SJ-inner table, remove the sj-nest */ - if ((remaining_tables & subq_tables) == subq_tables) + if (!tab->join->emb_sjm_nest) { - // All non-const tables of the SJ nest are in the remaining_tables. - // we are not in the nest anymore. - tab->join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables; - } - else - { - // Semi-join nest has: - // - a table being removed (not in the prefix) - // - some tables in the prefix. - tab->join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables; + table_map subq_tables= (emb_sj_nest->sj_inner_tables & + ~tab->join->const_table_map); + /* If we're removing the last SJ-inner table, remove the sj-nest */ + if ((remaining_tables & subq_tables) == subq_tables) + { + /* + All non-const tables of the SJ nest are in the remaining_tables. + we are not in the nest anymore. + */ + tab->join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables; + } + else + { + /* + Semi-join nest has: + - a table being removed (not in the prefix) + - some tables in the prefix. + */ + tab->join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables; + } } } @@ -3795,6 +3912,8 @@ at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab, static void recalculate_prefix_record_count(JOIN *join, uint start, uint end) { + DBUG_ASSERT(start >= join->const_tables); + for (uint j= start; j < end ;j++) { double prefix_count; @@ -3802,7 +3921,7 @@ static void recalculate_prefix_record_count(JOIN *join, uint start, uint end) prefix_count= 1.0; else prefix_count= COST_MULT(join->best_positions[j-1].prefix_record_count, - join->best_positions[j-1].records_read); + join->best_positions[j-1].records_out); join->best_positions[j].prefix_record_count= prefix_count; } @@ -3954,7 +4073,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) join->best_positions, i, FALSE, prefix_rec_count, join->best_positions + i, &dummy); - prefix_rec_count *= join->best_positions[i].records_read; + prefix_rec_count *= join->best_positions[i].records_out; rem_tables &= ~join->best_positions[i].table->table->map; } } @@ -3966,7 +4085,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) join->best_positions[first].n_sj_tables= tablenr - first + 1; POSITION dummy; // For loose scan paths double record_count= (first== join->const_tables)? 1.0: - join->best_positions[tablenr - 1].prefix_record_count; + join->best_positions[first - 1].prefix_record_count; table_map rem_tables= remaining_tables; uint idx; @@ -3996,7 +4115,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) TRUE /* no jbuf */, record_count, join->best_positions + idx, &dummy); } - record_count *= join->best_positions[idx].records_read; + record_count *= join->best_positions[idx].records_out; rem_tables &= ~join->best_positions[idx].table->table->map; } } @@ -4007,7 +4126,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) POSITION *first_pos= join->best_positions + first; POSITION loose_scan_pos; // For loose scan paths double record_count= (first== join->const_tables)? 1.0: - join->best_positions[tablenr - 1].prefix_record_count; + join->best_positions[first - 1].prefix_record_count; table_map rem_tables= remaining_tables; uint idx; @@ -4048,13 +4167,14 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) */ if (join->best_positions[idx].key) { + DBUG_ASSERT(join->best_positions[idx].type != JT_RANGE); delete join->best_positions[idx].table->quick; join->best_positions[idx].table->quick= NULL; } } } rem_tables &= ~join->best_positions[idx].table->table->map; - record_count *= join->best_positions[idx].records_read; + record_count *= join->best_positions[idx].records_out; } first_pos->sj_strategy= SJ_OPT_LOOSE_SCAN; first_pos->n_sj_tables= my_count_bits(first_pos->table->emb_sj_nest->sj_inner_tables); @@ -4777,7 +4897,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) DBUG_PRINT("info",("Creating group key in temporary table")); share->keys=1; share->uniques= MY_TEST(using_unique_constraint); - table->key_info=keyinfo; + table->key_info= share->key_info= keyinfo; keyinfo->key_part=key_part_info; keyinfo->flags=HA_NOSAME; keyinfo->usable_key_parts= keyinfo->user_defined_key_parts= 1; @@ -5271,7 +5391,8 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, Got a table that's not within any semi-join nest. This is a case like this: - SELECT * FROM ot1, nt1 WHERE ot1.col IN (SELECT expr FROM it1, it2) + SELECT * FROM ot1, nt1 WHERE + ot1.col IN (SELECT expr FROM it1, it2) with a join order of @@ -6531,18 +6652,14 @@ bool JOIN::choose_subquery_plan(table_map join_tables) IN/ALL/ANY optimizations are not applicable for so called fake select (this select exists only to filter results of union if it is needed). */ - if (select_lex == select_lex->master_unit()->fake_select_lex) - return 0; - - if (is_in_subquery()) - { - in_subs= unit->item->get_IN_subquery(); - if (in_subs->create_in_to_exists_cond(this)) - return true; - } - else + if (select_lex == select_lex->master_unit()->fake_select_lex || + likely(!is_in_subquery())) return false; + in_subs= unit->item->get_IN_subquery(); + if (in_subs->create_in_to_exists_cond(this)) + return true; + /* A strategy must be chosen earlier. */ DBUG_ASSERT(in_subs->has_strategy()); DBUG_ASSERT(in_to_exists_where || in_to_exists_having); @@ -6573,6 +6690,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables) /* The cost of the IN->EXISTS strategy. */ double in_exists_strategy_cost; double dummy; + const char *strategy; /* A. Estimate the number of rows of the outer table that will be filtered @@ -6634,7 +6752,6 @@ bool JOIN::choose_subquery_plan(table_map join_tables) /* Get the cost of the modified IN-EXISTS plan. */ inner_read_time_2= inner_join->best_read; - } else { @@ -6646,39 +6763,58 @@ bool JOIN::choose_subquery_plan(table_map join_tables) C. Compute execution costs. */ /* C.1 Compute the cost of the materialization strategy. */ - //uint rowlen= get_tmp_table_rec_length(unit->first_select()->item_list); - uint rowlen= get_tmp_table_rec_length(ref_ptrs, - select_lex->item_list.elements); - /* The cost of writing one row into the temporary table. */ - double write_cost= get_tmp_table_write_cost(thd, inner_record_count_1, - rowlen); - /* The cost of a lookup into the unique index of the materialized table. */ - double lookup_cost= get_tmp_table_lookup_cost(thd, inner_record_count_1, - rowlen); + bool blobs_used; + uint rowlen= get_tmp_table_rec_length(ref_ptrs, + select_lex->item_list.elements, + &blobs_used); + /* The cost of using the temp table */ + TMPTABLE_COSTS cost= get_tmp_table_costs(thd, inner_record_count_1, + rowlen, blobs_used, 1); /* The cost of executing the subquery and storing its result in an indexed temporary table. */ - double materialization_cost= COST_ADD(inner_read_time_1, - COST_MULT(write_cost, - inner_record_count_1)); + double materialization_cost= + COST_ADD(cost.create, + COST_ADD(inner_read_time_1, + COST_MULT((cost.write + WHERE_COST_THD(thd)), + inner_record_count_1))); - materialize_strategy_cost= COST_ADD(materialization_cost, - COST_MULT(outer_lookup_keys, - lookup_cost)); + materialize_strategy_cost= + COST_ADD(materialization_cost, + COST_MULT(outer_lookup_keys, cost.lookup)); /* C.2 Compute the cost of the IN=>EXISTS strategy. */ - in_exists_strategy_cost= COST_MULT(outer_lookup_keys, inner_read_time_2); + in_exists_strategy_cost= + COST_MULT(outer_lookup_keys, inner_read_time_2); /* C.3 Compare the costs and choose the cheaper strategy. */ if (materialize_strategy_cost >= in_exists_strategy_cost) + { in_subs->set_strategy(SUBS_IN_TO_EXISTS); + strategy= "in_to_exists"; + } else + { in_subs->set_strategy(SUBS_MATERIALIZATION); + strategy= "materialization"; + } + if (unlikely(thd->trace_started())) + { + Json_writer_object trace_wrapper(thd); + Json_writer_object trace_subquery(thd, "subquery_plan"); + trace_subquery. + add("rows", inner_record_count_1). + add("materialization_cost", materialize_strategy_cost). + add("in_exist_cost", in_exists_strategy_cost). + add("choosen", strategy); + } DBUG_PRINT("info", - ("mat_strategy_cost: %.2f, mat_cost: %.2f, write_cost: %.2f, lookup_cost: %.2f", - materialize_strategy_cost, materialization_cost, write_cost, lookup_cost)); + ("mat_strategy_cost: %.2f mat_cost: %.2f write_cost: %.2f " + "lookup_cost: %.2f", + materialize_strategy_cost, materialization_cost, cost.write, + cost.lookup)); DBUG_PRINT("info", ("inx_strategy_cost: %.2f, inner_read_time_2: %.2f", in_exists_strategy_cost, inner_read_time_2)); @@ -6704,6 +6840,13 @@ bool JOIN::choose_subquery_plan(table_map join_tables) implementation, fall back to IN-TO-EXISTS. */ in_subs->set_strategy(SUBS_IN_TO_EXISTS); + + if (unlikely(thd->trace_started())) + { + Json_writer_object trace_wrapper(thd); + Json_writer_object trace_subquery(thd, "subquery_plan_revert"); + trace_subquery.add("choosen", "in_to_exists"); + } } if (in_subs->test_strategy(SUBS_MATERIALIZATION)) diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h index 7b1b810ee81..1f121855d93 100644 --- a/sql/opt_subselect.h +++ b/sql/opt_subselect.h @@ -226,15 +226,18 @@ public: if (!(found_part & 1 ) && /* no usable ref access for 1st key part */ s->table->covering_keys.is_set(key)) { + double records, read_time; part1_conds_met= TRUE; + handler *file= s->table->file; DBUG_PRINT("info", ("Can use full index scan for LooseScan")); /* Calculate the cost of complete loose index scan. */ - double records= rows2double(s->table->file->stats.records); + records= rows2double(file->stats.records); /* The cost is entire index scan cost (divided by 2) */ - double read_time= s->table->file->keyread_time(key, 1, - (ha_rows) records); + read_time= file->cost(file->ha_keyread_and_copy_time(key, 1, + (ha_rows) records, + 0)); /* Now find out how many different keys we will get (for now we @@ -291,12 +294,14 @@ public: } } - void save_to_position(JOIN_TAB *tab, POSITION *pos) + void save_to_position(JOIN_TAB *tab, double record_count, POSITION *pos) { pos->read_time= best_loose_scan_cost; if (best_loose_scan_cost != DBL_MAX) { + pos->loops= record_count; pos->records_read= best_loose_scan_records; + pos->records_init= pos->records_out= pos->records_read; pos->key= best_loose_scan_start_key; pos->cond_selectivity= 1.0; pos->loosescan_picker.loosescan_key= best_loose_scan_key; @@ -320,7 +325,7 @@ void optimize_semi_joins(JOIN *join, table_map remaining_tables, uint idx, void update_sj_state(JOIN *join, const JOIN_TAB *new_tab, uint idx, table_map remaining_tables); void restore_prev_sj_state(const table_map remaining_tables, - const JOIN_TAB *tab, uint idx); + const JOIN_TAB *tab, uint idx); void fix_semijoin_strategies_for_picked_join_order(JOIN *join); diff --git a/sql/opt_trace.cc b/sql/opt_trace.cc index 4bc493940fb..1008690ccaa 100644 --- a/sql/opt_trace.cc +++ b/sql/opt_trace.cc @@ -149,7 +149,7 @@ void opt_trace_disable_if_no_security_context_access(THD *thd) return; } Opt_trace_context *const trace= &thd->opt_trace; - if (!thd->trace_started()) + if (unlikely(!thd->trace_started())) { /* @@optimizer_trace has "enabled=on" but trace is not started. @@ -201,7 +201,7 @@ void opt_trace_disable_if_no_stored_proc_func_access(THD *thd, sp_head *sp) if (likely(!(thd->variables.optimizer_trace & Opt_trace_context::FLAG_ENABLED)) || thd->system_thread || - !thd->trace_started()) + likely(!thd->trace_started())) return; Opt_trace_context *const trace= &thd->opt_trace; @@ -235,7 +235,7 @@ void opt_trace_disable_if_no_tables_access(THD *thd, TABLE_LIST *tbl) if (likely(!(thd->variables.optimizer_trace & Opt_trace_context::FLAG_ENABLED)) || thd->system_thread || - !thd->trace_started()) + likely(!thd->trace_started())) return; Opt_trace_context *const trace= &thd->opt_trace; @@ -296,7 +296,7 @@ void opt_trace_disable_if_no_view_access(THD *thd, TABLE_LIST *view, if (likely(!(thd->variables.optimizer_trace & Opt_trace_context::FLAG_ENABLED)) || thd->system_thread || - !thd->trace_started()) + likely(!thd->trace_started())) return; Opt_trace_context *const trace= &thd->opt_trace; @@ -562,43 +562,49 @@ void Opt_trace_stmt::set_allowed_mem_size(size_t mem_size) current_json->set_size_limit(mem_size); } + +void get_table_name_for_trace(const JOIN_TAB *tab, String *out) +{ + char table_name_buffer[64]; + DBUG_ASSERT(tab != NULL); + DBUG_ASSERT(tab->join->thd->trace_started()); + + if (tab->table && tab->table->derived_select_number) + { + /* Derived table name generation */ + size_t len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1, + "", + tab->table->derived_select_number); + out->copy(table_name_buffer, len, &my_charset_bin); + } + else if (tab->bush_children) + { + JOIN_TAB *ctab= tab->bush_children->start; + size_t len= my_snprintf(table_name_buffer, + sizeof(table_name_buffer)-1, + "", + ctab->emb_sj_nest->sj_subq_pred->get_identifier()); + out->copy(table_name_buffer, len, &my_charset_bin); + } + else + { + TABLE_LIST *real_table= tab->table->pos_in_table_list; + out->set(real_table->alias.str, real_table->alias.length, &my_charset_bin); + } +} + /* Prefer this when you are iterating over JOIN_TABs */ void Json_writer::add_table_name(const JOIN_TAB *tab) { - DBUG_ASSERT(tab->join->thd->trace_started()); - if (tab != NULL) - { - char table_name_buffer[SAFE_NAME_LEN]; - if (tab->table && tab->table->derived_select_number) - { - /* Derived table name generation */ - size_t len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1, - "", - tab->table->derived_select_number); - add_str(table_name_buffer, len); - } - else if (tab->bush_children) - { - JOIN_TAB *ctab= tab->bush_children->start; - size_t len= my_snprintf(table_name_buffer, - sizeof(table_name_buffer)-1, - "", - ctab->emb_sj_nest->sj_subq_pred->get_identifier()); - add_str(table_name_buffer, len); - } - else - { - TABLE_LIST *real_table= tab->table->pos_in_table_list; - add_str(real_table->alias.str, real_table->alias.length); - } - } - else - DBUG_ASSERT(0); + String sbuf; + get_table_name_for_trace(tab, &sbuf); + add_str(sbuf.ptr(), sbuf.length()); } + void Json_writer::add_table_name(const TABLE *table) { add_str(table->pos_in_table_list->alias.str); @@ -608,6 +614,7 @@ void Json_writer::add_table_name(const TABLE *table) void trace_condition(THD * thd, const char *name, const char *transform_type, Item *item, const char *table_name) { + DBUG_ASSERT(thd->trace_started()); Json_writer_object trace_wrapper(thd); Json_writer_object trace_cond(thd, transform_type); trace_cond.add("condition", name); @@ -623,8 +630,10 @@ void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab) Json_writer_object table_records(thd); table_records.add_table_name(tab); Json_writer_object table_rec(thd, "table_scan"); - table_rec.add("rows", tab->found_records) - .add("cost", tab->read_time); + table_rec. + add("rows", tab->found_records). + add("read_cost", tab->read_time). + add("read_and_compare_cost", tab->cached_scan_and_compare_time); } @@ -642,18 +651,26 @@ void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab) analysis of the various join orders. */ -void trace_plan_prefix(JOIN *join, uint idx, table_map join_tables) +void trace_plan_prefix(Json_writer_object *jsobj, JOIN *join, uint idx, + table_map join_tables) { - THD *const thd= join->thd; - DBUG_ASSERT(thd->trace_started()); + DBUG_ASSERT(join->thd->trace_started()); - Json_writer_array plan_prefix(thd, "plan_prefix"); - for (uint i= 0; i < idx; i++) + String prefix_str; + prefix_str.length(0); + for (uint i= join->const_tables; i < idx; i++) { TABLE_LIST *const tr= join->positions[i].table->tab_list; if (!(tr->map & join_tables)) - plan_prefix.add_table_name(join->positions[i].table); + { + String str; + get_table_name_for_trace(join->positions[i].table, &str); + if (prefix_str.length() != 0) + prefix_str.append(','); + prefix_str.append(str); + } } + jsobj->add("plan_prefix", prefix_str.ptr(), prefix_str.length()); } @@ -680,23 +697,30 @@ void print_final_join_order(JOIN *join) for (j= join->join_tab,i=0 ; i < join->top_join_tab_count; i++, j++) best_order.add_table_name(j); + best_order.end(); + + /* Write information about the resulting join */ + join_order. + add("rows", join->join_record_count). + add("cost", join->best_read); } -void print_best_access_for_table(THD *thd, POSITION *pos, - enum join_type type) +void print_best_access_for_table(THD *thd, POSITION *pos) { DBUG_ASSERT(thd->trace_started()); Json_writer_object obj(thd, "chosen_access_method"); - obj.add("type", type == JT_ALL ? "scan" : join_type_str[type]); - obj.add("records", pos->records_read); - obj.add("cost", pos->read_time); - obj.add("uses_join_buffering", pos->use_join_buffer); + obj. + add("type", pos->type == JT_ALL ? "scan" : join_type_str[pos->type]). + add("rows_read", pos->records_read). + add("rows_out", pos->records_out). + add("cost", pos->read_time). + add("uses_join_buffering", pos->use_join_buffer); if (pos->range_rowid_filter_info) { - uint key_no= pos->range_rowid_filter_info->key_no; - obj.add("rowid_filter_key", + uint key_no= pos->range_rowid_filter_info->get_key_no(); + obj.add("rowid_filter_index", pos->table->table->key_info[key_no].name); } } diff --git a/sql/opt_trace.h b/sql/opt_trace.h index 1ee23a33591..c6b5c4ea338 100644 --- a/sql/opt_trace.h +++ b/sql/opt_trace.h @@ -107,10 +107,10 @@ void opt_trace_print_expanded_query(THD *thd, SELECT_LEX *select_lex, Json_writer_object *trace_object); void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab); -void trace_plan_prefix(JOIN *join, uint idx, table_map join_tables); +void trace_plan_prefix(Json_writer_object *jsobj, JOIN *join, uint idx, + table_map join_tables); void print_final_join_order(JOIN *join); -void print_best_access_for_table(THD *thd, POSITION *pos, - enum join_type type); +void print_best_access_for_table(THD *thd, POSITION *pos); void trace_condition(THD * thd, const char *name, const char *transform_type, Item *item, const char *table_name= nullptr); diff --git a/sql/optimizer_costs.h b/sql/optimizer_costs.h new file mode 100644 index 00000000000..3b2300b9019 --- /dev/null +++ b/sql/optimizer_costs.h @@ -0,0 +1,162 @@ +#ifndef OPTIMIZER_COSTS_INCLUDED +#define OPTIMIZER_COSTS_INCLUDED +/* + Copyright (c) 2022, MariaDB AB + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA +*/ + +/* + This file defines costs structures and cost functions used by the optimizer +*/ + + +/* + OPTIMIZER_COSTS stores cost variables for each engine. They are stored + in linked_optimizer_costs (pointed to by handlerton) and TABLE_SHARE. +*/ + +#define OPTIMIZER_COST_UNDEF -1.0 +struct OPTIMIZER_COSTS +{ + double disk_read_cost; + double index_block_copy_cost; + double key_cmp_cost; + double key_copy_cost; + double key_lookup_cost; + double key_next_find_cost; + double disk_read_ratio; + double row_copy_cost; + double row_lookup_cost; + double row_next_find_cost; + double rowid_cmp_cost; + double rowid_copy_cost; + double initialized; // Set if default or connected with handlerton +}; + +/* Default optimizer costs */ +extern OPTIMIZER_COSTS default_optimizer_costs; +/* + These are used to avoid taking mutex while creating tmp tables + These are created once after the server is started so they are + not dynamic. +*/ +extern OPTIMIZER_COSTS heap_optimizer_costs, tmp_table_optimizer_costs; + +/* + Interface to the engine cost variables. See optimizer_defaults.h for + the default values. +*/ + +#define DISK_READ_RATIO costs->disk_read_ratio +#define KEY_LOOKUP_COST costs->key_lookup_cost +#define ROW_LOOKUP_COST costs->row_lookup_cost +#define INDEX_BLOCK_COPY_COST costs->index_block_copy_cost +#define KEY_COPY_COST costs->key_copy_cost +#define ROW_COPY_COST costs->row_copy_cost +#define ROW_COPY_COST_THD(THD) default_optimizer_costs.row_copy_cost +#define KEY_NEXT_FIND_COST costs->key_next_find_cost +#define ROW_NEXT_FIND_COST costs->row_next_find_cost +#define KEY_COMPARE_COST costs->key_cmp_cost +#define SORT_INDEX_CMP_COST default_optimizer_costs.key_cmp_cost +#define DISK_READ_COST costs->disk_read_cost +#define DISK_READ_COST_THD(thd) default_optimizer_costs.disk_read_cost + +/* Cost of comparing two rowids. This is set relative to KEY_COMPARE_COST */ +#define ROWID_COMPARE_COST costs->rowid_cmp_cost +#define ROWID_COMPARE_COST_THD(THD) default_optimizer_costs.rowid_cmp_cost + +/* Cost of comparing two rowids. This is set relative to KEY_COPY_COST */ +#define ROWID_COPY_COST costs->rowid_copy_cost + +/* Engine unrelated costs. Stored in THD so that the user can change them */ +#define WHERE_COST optimizer_where_cost +#define WHERE_COST_THD(THD) ((THD)->variables.optimizer_where_cost) +#define TABLE_SCAN_SETUP_COST optimizer_scan_setup_cost +#define TABLE_SCAN_SETUP_COST_THD(THD) (THD)->variables.optimizer_scan_setup_cost +#define INDEX_SCAN_SETUP_COST optimizer_scan_setup_cost/2 +/* Cost for doing duplicate removal in test_quick_select */ +#define DUPLICATE_REMOVAL_COST default_optimizer_costs.key_copy_cost + +/* Default fill factors of an (b-tree) index block is assumed to be 0.75 */ +#define INDEX_BLOCK_FILL_FACTOR_DIV 3 +#define INDEX_BLOCK_FILL_FACTOR_MUL 4 + +/* + These constants impact the cost of QSORT and priority queue sorting, + scaling the "n * log(n)" operations cost proportionally. + These factors are < 1.0 to scale down the sorting cost to be comparable + to 'read a row' = 1.0, (or 0.55 with default caching). + A factor of 0.1 makes the cost of get_pq_sort_cost(10, 10, false) =0.52 + (Reading 10 rows into a priority queue of 10 elements). + + One consenquence if this factor is too high is that priority_queue will + not use addon fields (to solve the sort without having to do an extra + re-read of rows) even if the number of LIMIT is low. +*/ +#define QSORT_SORT_SLOWNESS_CORRECTION_FACTOR (0.1) +#define PQ_SORT_SLOWNESS_CORRECTION_FACTOR (0.1) + +/* + Creating a record from the join cache is faster than getting a row from + the engine. JOIN_CACHE_ROW_COPY_COST_FACTOR is the factor used to + take this into account. This is multiplied with ROW_COPY_COST. +*/ +#define JOIN_CACHE_ROW_COPY_COST_FACTOR(thd) 1.0 + +/* + cost1 is better that cost2 only if cost1 + COST_EPS < cost2 + The main purpose of this is to ensure we use the first index or plan + when there are identical plans. Without COST_EPS some plans in the + test suite would vary depending on floating point calculations done + in different paths. +*/ +#define COST_EPS 0.0000001 + +#define COST_MAX (DBL_MAX * (1.0 - DBL_EPSILON)) + +static inline double COST_ADD(double c, double d) +{ + DBUG_ASSERT(c >= 0); + DBUG_ASSERT(d >= 0); + return (COST_MAX - (d) > (c) ? (c) + (d) : COST_MAX); +} + +static inline double COST_MULT(double c, double f) +{ + DBUG_ASSERT(c >= 0); + DBUG_ASSERT(f >= 0); + return (COST_MAX / (f) > (c) ? (c) * (f) : COST_MAX); +} + +OPTIMIZER_COSTS *get_optimizer_costs(const LEX_CSTRING *cache_name); +OPTIMIZER_COSTS *create_optimizer_costs(const char *name, size_t length); +OPTIMIZER_COSTS *get_or_create_optimizer_costs(const char *name, + size_t length); +bool create_default_optimizer_costs(); +void copy_tmptable_optimizer_costs(); +void free_all_optimizer_costs(); +struct TABLE; + +extern "C" +{ + typedef int (*process_optimizer_costs_t) (const LEX_CSTRING *, + const OPTIMIZER_COSTS *, + TABLE *); + bool process_optimizer_costs(process_optimizer_costs_t func, TABLE *param); +} + + +#endif /* OPTIMIZER_COSTS_INCLUDED */ diff --git a/sql/optimizer_defaults.h b/sql/optimizer_defaults.h new file mode 100644 index 00000000000..a3c22d898cf --- /dev/null +++ b/sql/optimizer_defaults.h @@ -0,0 +1,190 @@ +#ifndef OPTIMIZER_DEFAULTS_INCLUDED +#define OPTIMIZER_DEFAULTS_INCLUDED +/* + Copyright (c) 2022, MariaDB AB + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA +*/ + +/* + This file contains costs constants used by the optimizer + All costs should be based on milliseconds (1 cost = 1 ms) +*/ + +/* Cost for finding the first key in a key scan */ +#define DEFAULT_KEY_LOOKUP_COST ((double) 0.000435777) + +/* Cost of finding a row based on row_ID */ +#define DEFAULT_ROW_LOOKUP_COST ((double) 0.000130839) + +/* + Cost of finding and copying key and row blocks from the storage + engine index cache to an internal cache as part of an index + scan. This includes all mutexes that needs to be taken to get + exclusive access to a page. The number is taken from accessing an + existing blocks from Aria page cache. + Used in handler::scan_time() and handler::keyread_time() +*/ +#define DEFAULT_INDEX_BLOCK_COPY_COST ((double) 3.56e-05) + +/* + Cost of copying a row to 'table->record'. + Used by scan_time() and rnd_pos_time() methods. + + If this is too small, then table scans will be prefered over 'ref' + as with table scans there are no key read (KEY_LOOKUP_COST), fewer + disk reads but more record copying and row comparisions. If it's + too big then MariaDB will used key lookup even when table scan is + better. +*/ +#define DEFAULT_ROW_COPY_COST ((double) 0.000060866) + +/* + Cost of copying the key to 'table->record' + + If this is too small, then, for small tables, index scans will be + prefered over 'ref' as with index scans there are fewer disk reads. +*/ +#define DEFAULT_KEY_COPY_COST ((double) 0.000015685) + +/* + Cost of finding the next index entry and checking its rowid against filter + This cost is very low as it's done inside the storage engine. + Should be smaller than KEY_COPY_COST. + */ +#define DEFAULT_KEY_NEXT_FIND_COST ((double) 0.000082347) + +/* Cost of finding the next row when scanning a table */ +#define DEFAULT_ROW_NEXT_FIND_COST ((double) 0.000045916) + +/** + The cost of executing the WHERE clause as part of any row check. + Increasing this would force the optimizer to use row combinations + that reads fewer rows. + The default cost comes from recording times from a simple where clause that + compares two fields (date and a double) with constants. +*/ +#define DEFAULT_WHERE_COST ((double) 3.2e-05) + +/* The cost of comparing a key when using range access or sorting */ +#define DEFAULT_KEY_COMPARE_COST 0.000011361 + +/* Rowid compare is usually just a single memcmp of a short string */ +#define DEFAULT_ROWID_COMPARE_COST 0.000002653 +/* Rowid copy is usually just a single memcpy of a short string */ +#define DEFAULT_ROWID_COPY_COST 0.000002653 + +/* + Cost modifiers rowid_filter. These takes into account the overhead of + using and calling Rowid_filter_sorted_array::check() from the engine +*/ +#define ROWID_FILTER_PER_CHECK_MODIFIER 4 /* times key_copy_cost */ +#define ROWID_FILTER_PER_ELEMENT_MODIFIER 3 /* times rowid_compare_cost */ + +/* + Average disk seek time on a hard disk is 8-10 ms, which is also + about the time to read a IO_SIZE (8192) block. + + A medium ssd is about 400MB/second, which gives us the time for + reading an IO_SIZE block to IO_SIZE/400000000 = 0.0000204 sec= 0.02 ms. +*/ +#define DEFAULT_DISK_READ_COST ((double) IO_SIZE / 400000000.0 * 1000) + +/* + The follwoing is an old comment for hard-disks, please ignore the + following, except if you like history: + + For sequential hard disk seeks the cost formula is: + DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST * #blocks_to_skip + + The cost of average seek + DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST*BLOCKS_IN_AVG_SEEK = 10. +*/ + + +/* + The table/index cache_miss/total_cache_request ratio. + 1.0 means that a searched for key or row will never be in the cache while + 0.0 means it always in the cache (and we don't have to do any disk reads). + + According to folklore, one should not have to access disk for more + than 20% of the cache request for MariaDB to run very well. + However in practice when we read rows or keys in a query, we will often + read the same row over and over again. Because of this we set + DEFAULT_DISK_READ_RATIO to 0.20/10 = 0.02. + + Increasing DISK_READ_RATIO will make MariaDB prefer key lookup over + table scans as the impact of ROW_COPY_COST and INDEX_COPY cost will + have a larger impact when more rows are examined.. + + We are not yet taking into account cache usage statistics as this + could confuse users as the EXPLAIN and costs for a query would change + between to query calls, which may confuse users (and also make the + mtr tests very unpredictable). + + Note that the engine's avg_io_cost() (DEFAULT_DISK_READ_COST by default) + is multiplied with this constant! +*/ + +#define DEFAULT_DISK_READ_RATIO 0.02 + +/* + The following costs are mainly to ensure we don't do table and index + scans for small tables, like the one we have in the mtr test suite. + + This is mostly to keep the mtr tests use indexes (as the optimizer would + if the tables are large). It will also ensure that EXPLAIN is showing + more key user for users where they are testing queries with small tables + at the start of projects. + This is probably OK for most a the execution time difference between table + scan and index scan compared to key lookups so small when using small + tables. It also helps to fill the index cache which will help mitigate + the speed difference. +*/ + +/* + Extra cost for full table and index scan. Used to prefer key and range + over index and table scans + + INDEX_SCAN_SETUP_COST (defined in optimizer_costs.h) is half of + table_scan_setup_cost to get the optimizer to prefer index scans to table + scans as key copy is faster than row copy and index blocks provides + more information in the cache. + + This will also help MyISAM as with MyISAM the table scans has a cost + very close to index scans (they are fast but require a read call + that we want to avoid even if it's small). + + 10 usec is about 10 MyISAM row lookups with optimizer_disk_read_ratio= 0.02 +*/ +#define DEFAULT_TABLE_SCAN_SETUP_COST 0.01 // 10 usec + +/* Extra cost for doing a range scan. Used to prefer 'ref' over range */ +#define MULTI_RANGE_READ_SETUP_COST KEY_LOOKUP_COST + +/* + Temporary file and temporary table related costs + Used with subquery materialization, derived tables etc +*/ + +#define TMPFILE_CREATE_COST 0.5 // Cost of creating and deleting files +#define HEAP_TEMPTABLE_CREATE_COST 0.025 // ms +/* Cost taken from HEAP_LOOKUP_COST in ha_heap.cc */ +#define HEAP_TEMPTABLE_LOOKUP_COST (0.00016097) +#define DISK_TEMPTABLE_LOOKUP_COST(thd) (tmp_table_optimizer_costs.key_lookup_cost + tmp_table_optimizer_costs.row_lookup_cost + tmp_table_optimizer_costs.row_copy_cost) +#define DISK_TEMPTABLE_CREATE_COST TMPFILE_CREATE_COST*2 // 2 tmp tables +#define DISK_TEMPTABLE_BLOCK_SIZE IO_SIZE + +#endif /* OPTIMIZER_DEFAULTS_INCLUDED */ diff --git a/sql/records.cc b/sql/records.cc index 3aad36ca862..5b2ebefe14f 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -400,11 +400,8 @@ static int rr_handle_error(READ_RECORD *info, int error) static int rr_quick(READ_RECORD *info) { int tmp; - while ((tmp= info->select->quick->get_next())) - { + if ((tmp= info->select->quick->get_next())) tmp= rr_handle_error(info, tmp); - break; - } return tmp; } @@ -427,16 +424,14 @@ static int rr_index_first(READ_RECORD *info) int tmp; // tell handler that we are doing an index scan if ((tmp = info->table->file->prepare_index_scan())) - { - tmp= rr_handle_error(info, tmp); - return tmp; - } + goto err; - tmp= info->table->file->ha_index_first(info->record()); info->read_record_func= rr_index; - if (tmp) - tmp= rr_handle_error(info, tmp); - return tmp; + if (!(tmp= info->table->file->ha_index_first(info->record()))) + return tmp; + +err: + return rr_handle_error(info, tmp); } @@ -455,9 +450,9 @@ static int rr_index_first(READ_RECORD *info) static int rr_index_last(READ_RECORD *info) { - int tmp= info->table->file->ha_index_last(info->record()); + int tmp; info->read_record_func= rr_index_desc; - if (tmp) + if ((tmp= info->table->file->ha_index_last(info->record()))) tmp= rr_handle_error(info, tmp); return tmp; } diff --git a/sql/rowid_filter.cc b/sql/rowid_filter.cc index 0589b587ba2..f034c045938 100644 --- a/sql/rowid_filter.cc +++ b/sql/rowid_filter.cc @@ -19,17 +19,21 @@ #include "sql_class.h" #include "opt_range.h" #include "rowid_filter.h" +#include "optimizer_defaults.h" #include "sql_select.h" #include "opt_trace.h" +/* + key_next_find_cost below is the cost of finding the next possible key + and calling handler_rowid_filter_check() to check it against the filter +*/ -inline -double Range_rowid_filter_cost_info::lookup_cost( - Rowid_filter_container_type cont_type) +double Range_rowid_filter_cost_info:: +lookup_cost(Rowid_filter_container_type cont_type) { switch (cont_type) { case SORTED_ARRAY_CONTAINER: - return log(est_elements)*0.01; + return log(est_elements) * rowid_compare_cost + base_lookup_cost; default: DBUG_ASSERT(0); return 0; @@ -39,14 +43,16 @@ double Range_rowid_filter_cost_info::lookup_cost( /** @brief - The average gain in cost per row to use the range filter with this cost info + The average gain in cost per row to use the range filter with this cost + info */ inline -double Range_rowid_filter_cost_info::avg_access_and_eval_gain_per_row( - Rowid_filter_container_type cont_type) +double Range_rowid_filter_cost_info:: +avg_access_and_eval_gain_per_row(Rowid_filter_container_type cont_type, + double cost_of_row_fetch) { - return (1+1.0/TIME_FOR_COMPARE) * (1 - selectivity) - + return (cost_of_row_fetch + where_cost) * (1 - selectivity) - lookup_cost(cont_type); } @@ -58,8 +64,9 @@ double Range_rowid_filter_cost_info::avg_access_and_eval_gain_per_row( @param access_cost_factor the adjusted cost of access a row @details - The current code to estimate the cost of a ref access is quite inconsistent: - in some cases the effect of page buffers is taken into account, for others + The current code to estimate the cost of a ref access is quite + inconsistent: + In some cases the effect of page buffers is taken into account, for others just the engine dependent read_time() is employed. That's why the average cost of one random seek might differ from 1. The parameter access_cost_factor can be considered as the cost of a random @@ -74,10 +81,11 @@ double Range_rowid_filter_cost_info::avg_access_and_eval_gain_per_row( */ inline -double Range_rowid_filter_cost_info::avg_adjusted_gain_per_row( - double access_cost_factor) +double Range_rowid_filter_cost_info:: +avg_adjusted_gain_per_row(double access_cost_factor) { - return a - (1 - access_cost_factor) * (1 - selectivity); + DBUG_ASSERT(access_cost_factor >= 0.0 && access_cost_factor <= 1.0); + return gain - (1 - access_cost_factor) * (1 - selectivity); } @@ -91,10 +99,11 @@ double Range_rowid_filter_cost_info::avg_adjusted_gain_per_row( */ inline void -Range_rowid_filter_cost_info::set_adjusted_gain_param(double access_cost_factor) +Range_rowid_filter_cost_info:: +set_adjusted_gain_param(double access_cost_factor) { - a_adj= avg_adjusted_gain_per_row(access_cost_factor); - cross_x_adj= b / a_adj; + gain_adj= avg_adjusted_gain_per_row(access_cost_factor); + cross_x_adj= cost_of_building_range_filter / gain_adj; } @@ -116,13 +125,20 @@ void Range_rowid_filter_cost_info::init(Rowid_filter_container_type cont_type, table= tab; key_no= idx; est_elements= (ulonglong) table->opt_range[key_no].rows; - b= build_cost(container_type); + cost_of_building_range_filter= build_cost(container_type); + + where_cost= tab->in_use->variables.optimizer_where_cost; + base_lookup_cost= (ROWID_FILTER_PER_CHECK_MODIFIER * + tab->file->KEY_COPY_COST); + rowid_compare_cost= (ROWID_FILTER_PER_ELEMENT_MODIFIER * + tab->file->ROWID_COMPARE_COST); selectivity= est_elements/((double) table->stat_records()); - a= avg_access_and_eval_gain_per_row(container_type); - if (a > 0) - cross_x= b/a; + gain= avg_access_and_eval_gain_per_row(container_type, + tab->file->ROW_LOOKUP_COST); + if (gain > 0) + cross_x= cost_of_building_range_filter/gain; else - cross_x= b+1; + cross_x= cost_of_building_range_filter+1; abs_independent.clear_all(); } @@ -135,16 +151,19 @@ void Range_rowid_filter_cost_info::init(Rowid_filter_container_type cont_type, double Range_rowid_filter_cost_info::build_cost(Rowid_filter_container_type cont_type) { - double cost= 0; + double cost; + OPTIMIZER_COSTS *costs= &table->s->optimizer_costs; DBUG_ASSERT(table->opt_range_keys.is_set(key_no)); - cost+= table->opt_range[key_no].index_only_cost; + /* Cost of fetching keys */ + cost= table->opt_range[key_no].index_only_fetch_cost(table); switch (cont_type) { - case SORTED_ARRAY_CONTAINER: - cost+= ARRAY_WRITE_COST * est_elements; /* cost filling the container */ - cost+= ARRAY_SORT_C * est_elements * log(est_elements); /* sorting cost */ + /* Add cost of filling container and cost of sorting */ + cost= (est_elements * + (costs->rowid_copy_cost + // Copying rowid + costs->rowid_cmp_cost * log2(est_elements))); // Sort break; default: DBUG_ASSERT(0); @@ -177,7 +196,7 @@ int compare_range_rowid_filter_cost_info_by_a( Range_rowid_filter_cost_info **filter_ptr_1, Range_rowid_filter_cost_info **filter_ptr_2) { - double diff= (*filter_ptr_2)->get_a() - (*filter_ptr_1)->get_a(); + double diff= (*filter_ptr_2)->get_gain() - (*filter_ptr_1)->get_gain(); return (diff < 0 ? -1 : (diff > 0 ? 1 : 0)); } @@ -204,7 +223,8 @@ void TABLE::prune_range_rowid_filters() the elements if this bit matrix. */ - Range_rowid_filter_cost_info **filter_ptr_1= range_rowid_filter_cost_info_ptr; + Range_rowid_filter_cost_info **filter_ptr_1= + range_rowid_filter_cost_info_ptr; for (uint i= 0; i < range_rowid_filter_cost_info_elems; i++, filter_ptr_1++) @@ -243,7 +263,7 @@ void TABLE::prune_range_rowid_filters() */ Range_rowid_filter_cost_info **cand_filter_ptr= - range_rowid_filter_cost_info_ptr; + range_rowid_filter_cost_info_ptr; for (uint i= 0; i < range_rowid_filter_cost_info_elems; i++, cand_filter_ptr++) @@ -361,9 +381,7 @@ void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd) */ while ((key_no= it++) != key_map::Iterator::BITMAP_END) { - if (!(file->index_flags(key_no, 0, 1) & HA_DO_RANGE_FILTER_PUSHDOWN)) // !1 - continue; - if (file->is_clustering_key(key_no)) // !2 + if (!can_use_rowid_filter(key_no)) // 1 & 2 continue; if (opt_range[key_no].rows > get_max_range_rowid_filter_elems_for_table(thd, this, @@ -418,6 +436,7 @@ void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd) void TABLE::trace_range_rowid_filters(THD *thd) const { + DBUG_ASSERT(thd->trace_started()); if (!range_rowid_filter_cost_info_elems) return; @@ -435,45 +454,56 @@ void TABLE::trace_range_rowid_filters(THD *thd) const void Range_rowid_filter_cost_info::trace_info(THD *thd) { + DBUG_ASSERT(thd->trace_started()); Json_writer_object js_obj(thd); - js_obj.add("key", table->key_info[key_no].name); - js_obj.add("build_cost", b); - js_obj.add("rows", est_elements); + js_obj. + add("key", table->key_info[key_no].name). + add("build_cost", cost_of_building_range_filter). + add("rows", est_elements); } /** @brief Choose the best range filter for the given access of the table - @param access_key_no The index by which the table is accessed - @param records The estimated total number of key tuples with this access - @param access_cost_factor the cost of a random seek to access the table - + @param access_key_no The index by which the table is accessed + @param records The estimated total number of key tuples with + this access + @param fetch_cost_factor The cost of fetching 'records' rows + @param index_only_cost The cost of fetching 'records' rows with + index only reads + @param prev_records How many row combinations we have in + preceding tables + @parma records_out Will be updated to the minimum result rows for any + usable filter. @details The function looks through the array of cost info for range filters and chooses the element for the range filter that promise the greatest gain with the the ref or range access of the table by access_key_no. - As the array is sorted by cross_x in ascending order the function stops - the look through as soon as it reaches the first element with - cross_x_adj > records because the range filter for this element and the - range filters for all remaining elements do not promise positive gains. - @note - It is easy to see that if cross_x[i] > cross_x[j] then - cross_x_adj[i] > cross_x_adj[j] + The function assumes that caller has checked that the key is not a clustered + key. See best_access_path(). @retval Pointer to the cost info for the range filter that promises the greatest gain, NULL if there is no such range filter */ Range_rowid_filter_cost_info * -TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no, - double records, - double access_cost_factor) +TABLE::best_range_rowid_filter(uint access_key_no, double records, + double fetch_cost, double index_only_cost, + double prev_records, double *records_out) { if (range_rowid_filter_cost_info_elems == 0 || covering_keys.is_set(access_key_no)) return 0; + /* + Currently we do not support usage of range filters if the table + is accessed by the clustered primary key. It does not make sense + if a full key is used. If the table is accessed by a partial + clustered primary key it would, but the current InnoDB code does not + allow it. Later this limitation may be lifted. + */ + DBUG_ASSERT(!file->is_clustering_key(access_key_no)); // Disallow use of range filter if the key contains partially-covered // columns. @@ -483,46 +513,38 @@ TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no, return 0; } - /* - Currently we do not support usage of range filters if the table - is accessed by the clustered primary key. It does not make sense - if a full key is used. If the table is accessed by a partial - clustered primary key it would, but the current InnoDB code does not - allow it. Later this limitation will be lifted - */ - if (file->is_clustering_key(access_key_no)) - return 0; - Range_rowid_filter_cost_info *best_filter= 0; - double best_filter_gain= 0; + double best_filter_gain= DBL_MAX; key_map no_filter_usage= key_info[access_key_no].overlapped; no_filter_usage.merge(key_info[access_key_no].constraint_correlated); + no_filter_usage.set_bit(access_key_no); for (uint i= 0; i < range_rowid_filter_cost_info_elems ; i++) { - double curr_gain = 0; + double new_cost, new_total_cost, new_records; + double cost_of_accepted_rows, cost_of_rejected_rows; Range_rowid_filter_cost_info *filter= range_rowid_filter_cost_info_ptr[i]; /* Do not use a range filter that uses an in index correlated with the index by which the table is accessed */ - if ((filter->key_no == access_key_no) || - no_filter_usage.is_set(filter->key_no)) + if (no_filter_usage.is_set(filter->key_no)) continue; - filter->set_adjusted_gain_param(access_cost_factor); + new_records= records * filter->selectivity; + set_if_smaller(*records_out, new_records); + cost_of_accepted_rows= fetch_cost * filter->selectivity; + cost_of_rejected_rows= index_only_cost * (1 - filter->selectivity); + new_cost= (cost_of_accepted_rows + cost_of_rejected_rows + + records * filter->lookup_cost()); + new_total_cost= ((new_cost + new_records * + in_use->variables.optimizer_where_cost) * + prev_records + filter->get_setup_cost()); - if (records < filter->cross_x_adj) + if (best_filter_gain > new_total_cost) { - /* Does not make sense to look through the remaining filters */ - break; - } - - curr_gain= filter->get_adjusted_gain(records); - if (best_filter_gain < curr_gain) - { - best_filter_gain= curr_gain; + best_filter_gain= new_total_cost; best_filter= filter; } } @@ -570,41 +592,40 @@ bool Range_rowid_filter::fill() file->pushed_idx_cond_keyno= MAX_KEY; file->in_range_check_pushed_down= false; - /* We're going to just read rowids / primary keys */ + /* We're going to just read rowids / clustered primary keys */ table->prepare_for_position(); - table->file->ha_start_keyread(quick->index); + file->ha_start_keyread(quick->index); if (quick->init() || quick->reset()) - rc= 1; + goto end; - while (!rc) + while (!(rc= quick->get_next())) { - rc= quick->get_next(); - if (thd->killed) - rc= 1; - if (!rc) + file->position(quick->record); + if (container->add(NULL, (char*) file->ref) || thd->killed) { - file->position(quick->record); - if (container->add(NULL, (char*) file->ref)) - rc= 1; - else - tracker->increment_container_elements_count(); + rc= 1; + break; } } +end: quick->range_end(); - table->file->ha_end_keyread(); + file->ha_end_keyread(); table->status= table_status_save; file->pushed_idx_cond= pushed_idx_cond_save; file->pushed_idx_cond_keyno= pushed_idx_cond_keyno_save; file->in_range_check_pushed_down= in_range_check_pushed_down_save; - tracker->report_container_buff_size(table->file->ref_length); + + tracker->set_container_elements_count(container->elements()); + tracker->report_container_buff_size(file->ref_length); if (rc != HA_ERR_END_OF_FILE) return 1; - table->file->rowid_filter_is_active= true; + container->sort(refpos_order_cmp, (void *) file); + file->rowid_filter_is_active= container->elements() != 0; return 0; } @@ -628,18 +649,13 @@ bool Range_rowid_filter::fill() bool Rowid_filter_sorted_array::check(void *ctxt, char *elem) { - TABLE *table= (TABLE *) ctxt; - if (!is_checked) - { - refpos_container.sort(refpos_order_cmp, (void *) (table->file)); - is_checked= true; - } + handler *file= ((TABLE *) ctxt)->file; int l= 0; int r= refpos_container.elements()-1; while (l <= r) { int m= (l + r) / 2; - int cmp= refpos_order_cmp((void *) (table->file), + int cmp= refpos_order_cmp((void *) file, refpos_container.get_pos(m), elem); if (cmp == 0) return true; @@ -656,14 +672,6 @@ Range_rowid_filter::~Range_rowid_filter() { delete container; container= 0; - if (select) - { - if (select->quick) - { - delete select->quick; - select->quick= 0; - } - delete select; - select= 0; - } + delete select; + select= 0; } diff --git a/sql/rowid_filter.h b/sql/rowid_filter.h index cb1615c5925..c80281385ea 100644 --- a/sql/rowid_filter.h +++ b/sql/rowid_filter.h @@ -143,13 +143,6 @@ class SQL_SELECT; class Rowid_filter_container; class Range_rowid_filter_cost_info; -/* Cost to write rowid into array */ -#define ARRAY_WRITE_COST 0.005 -/* Factor used to calculate cost of sorting rowids in array */ -#define ARRAY_SORT_C 0.01 -/* Cost to evaluate condition */ -#define COST_COND_EVAL 0.2 - typedef enum { SORTED_ARRAY_CONTAINER, @@ -193,7 +186,10 @@ public: virtual bool check(void *ctxt, char *elem) = 0; /* True if the container does not contain any element */ - virtual bool is_empty() = 0; + bool is_empty() { return elements() == 0; } + virtual uint elements() = 0; + virtual void sort (int (*cmp) (void *ctxt, const void *el1, const void *el2), + void *cmp_arg) = 0; virtual ~Rowid_filter_container() {} }; @@ -269,9 +265,9 @@ public: ~Range_rowid_filter(); - bool build() { return fill(); } + bool build() override { return fill(); } - bool check(char *elem) + bool check(char *elem) override { if (container->is_empty()) return false; @@ -303,52 +299,49 @@ class Refpos_container_sorted_array : public Sql_alloc /* Number of bytes allocated for an element */ uint elem_size; /* The dynamic array over which the wrapper is built */ - Dynamic_array *array; + DYNAMIC_ARRAY array; + DYNAMIC_ARRAY_APPEND append; public: Refpos_container_sorted_array(uint max_elems, uint elem_sz) - : max_elements(max_elems), elem_size(elem_sz), array(0) {} + :max_elements(max_elems), elem_size(elem_sz) + { + bzero(&array, sizeof(array)); + } ~Refpos_container_sorted_array() { - delete array; - array= 0; + delete_dynamic(&array); } bool alloc() { - array= new Dynamic_array (PSI_INSTRUMENT_MEM, - elem_size * max_elements, - elem_size * max_elements/sizeof(char) + 1); - return array == NULL; + /* This can never fail as things will be allocated on demand */ + init_dynamic_array2(PSI_INSTRUMENT_MEM, &array, elem_size, 0, + max_elements, 512, MYF(0)); + init_append_dynamic(&append, &array); + return 0; } - bool add(char *elem) + bool add(const char *elem) { - for (uint i= 0; i < elem_size; i++) - { - if (array->append(elem[i])) - return true; - } - return false; + return append_dynamic(&append, elem); } - char *get_pos(uint n) + inline uchar *get_pos(uint n) const { - return array->get_pos(n * elem_size); + return dynamic_array_ptr(&array, n); } - uint elements() { return (uint) (array->elements() / elem_size); } + inline uint elements() const { return (uint) array.elements; } void sort (int (*cmp) (void *ctxt, const void *el1, const void *el2), void *cmp_arg) { - my_qsort2(array->front(), array->elements()/elem_size, + my_qsort2(array.buffer, array.elements, elem_size, (qsort2_cmp) cmp, cmp_arg); } - - bool is_empty() { return elements() == 0; } }; @@ -363,23 +356,29 @@ class Rowid_filter_sorted_array: public Rowid_filter_container { /* The dynamic array to store rowids / primary keys */ Refpos_container_sorted_array refpos_container; - /* Initially false, becomes true after the first call of (check() */ - bool is_checked; public: Rowid_filter_sorted_array(uint elems, uint elem_size) - : refpos_container(elems, elem_size), is_checked(false) {} + : refpos_container(elems, elem_size) {} - Rowid_filter_container_type get_type() + Rowid_filter_container_type get_type() override { return SORTED_ARRAY_CONTAINER; } - bool alloc() { return refpos_container.alloc(); } + bool alloc() override { return refpos_container.alloc(); } - bool add(void *ctxt, char *elem) { return refpos_container.add(elem); } + bool add(void *ctxt, char *elem) override + { return refpos_container.add(elem); } - bool check(void *ctxt, char *elem); + bool check(void *ctxt, char *elem) override; + + uint elements() override { return refpos_container.elements(); } + + void sort (int (*cmp) (void *ctxt, const void *el1, const void *el2), + void *cmp_arg) override + { + return refpos_container.sort(cmp, cmp_arg); + } - bool is_empty() { return refpos_container.is_empty(); } }; /** @@ -390,20 +389,24 @@ public: whether usage of the range filter promises some gain. */ -class Range_rowid_filter_cost_info : public Sql_alloc +class Range_rowid_filter_cost_info final: public Sql_alloc { /* The table for which the range filter is to be built (if needed) */ TABLE *table; /* Estimated number of elements in the filter */ ulonglong est_elements; - /* The cost of building the range filter */ - double b; + /* The index whose range scan would be used to build the range filter */ + uint key_no; + double cost_of_building_range_filter; + double where_cost, base_lookup_cost, rowid_compare_cost; + /* - a*N-b yields the gain of the filter - for N key tuples of the index key_no + (gain*row_combinations)-cost_of_building_range_filter yields the gain of + the filter for 'row_combinations' key tuples of the index key_no + calculated with avg_access_and_eval_gain_per_row(container_type); */ - double a; - /* The value of N where the gain is 0 */ + double gain; + /* The value of row_combinations where the gain is 0 */ double cross_x; /* Used for pruning of the potential range filters */ key_map abs_independent; @@ -412,16 +415,14 @@ class Range_rowid_filter_cost_info : public Sql_alloc These two parameters are used to choose the best range filter in the function TABLE::best_range_rowid_filter_for_partial_join */ - double a_adj; + double gain_adj; double cross_x_adj; public: - /* The type of the container of the range filter */ - Rowid_filter_container_type container_type; - /* The index whose range scan would be used to build the range filter */ - uint key_no; /* The selectivity of the range filter */ double selectivity; + /* The type of the container of the range filter */ + Rowid_filter_container_type container_type; Range_rowid_filter_cost_info() : table(0), key_no(0) {} @@ -430,39 +431,44 @@ public: double build_cost(Rowid_filter_container_type container_type); - inline double lookup_cost(Rowid_filter_container_type cont_type); + double lookup_cost(Rowid_filter_container_type cont_type); + inline double lookup_cost() { return lookup_cost(container_type); } inline double - avg_access_and_eval_gain_per_row(Rowid_filter_container_type cont_type); + avg_access_and_eval_gain_per_row(Rowid_filter_container_type cont_type, + double cost_of_row_fetch); inline double avg_adjusted_gain_per_row(double access_cost_factor); inline void set_adjusted_gain_param(double access_cost_factor); /* Get the gain that usage of filter promises for r key tuples */ - inline double get_gain(double r) + inline double get_gain(double row_combinations) { - return r * a - b; + return row_combinations * gain - cost_of_building_range_filter; } /* Get the adjusted gain that usage of filter promises for r key tuples */ - inline double get_adjusted_gain(double r) + inline double get_adjusted_gain(double row_combinations) { - return r * a_adj - b; + return row_combinations * gain_adj - cost_of_building_range_filter; } /* The gain promised by usage of the filter for r key tuples due to less condition evaluations */ - inline double get_cmp_gain(double r) + inline double get_cmp_gain(double row_combinations) { - return r * (1 - selectivity) / TIME_FOR_COMPARE; + return (row_combinations * (1 - selectivity) * where_cost); } Rowid_filter_container *create_container(); - double get_a() { return a; } + double get_setup_cost() { return cost_of_building_range_filter; } + double get_lookup_cost(); + double get_gain() { return gain; } + uint get_key_no() { return key_no; } void trace_info(THD *thd); @@ -472,11 +478,20 @@ public: friend void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd); + /* Best range row id filter for parital join */ friend Range_rowid_filter_cost_info * - TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no, - double records, - double access_cost_factor); + TABLE::best_range_rowid_filter(uint access_key_no, + double records, + double fetch_cost, + double index_only_cost, + double prev_records, + double *records_out); + Range_rowid_filter_cost_info * + apply_filter(THD *thd, TABLE *table, ALL_READ_COST *cost, + double *records_arg, + double *startup_cost, + uint ranges, double record_count); }; #endif /* ROWID_FILTER_INCLUDED */ diff --git a/sql/set_var.cc b/sql/set_var.cc index aa9ec5ab5ca..b49040b8ec3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -310,7 +310,7 @@ do { \ case SHOW_HA_ROWS: do_num_val (ha_rows,CMD); #define case_for_double(CMD) \ - case SHOW_DOUBLE: do_num_val (double,CMD) + case SHOW_DOUBLE: do_num_val (double,CMD); #define case_get_string_as_lex_string \ case SHOW_CHAR: \ @@ -1550,4 +1550,3 @@ ulonglong get_system_variable_hash_version(void) { return system_variable_hash_version; } - diff --git a/sql/set_var.h b/sql/set_var.h index 1cd0ddb6e7a..471d76129d4 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -84,7 +84,7 @@ protected: typedef bool (*on_update_function)(sys_var *self, THD *thd, enum_var_type type); int flags; ///< or'ed flag_enum values - const SHOW_TYPE show_val_type; ///< what value_ptr() returns for sql_show.cc + SHOW_TYPE show_val_type; ///< what value_ptr() returns for sql_show.cc PolyLock *guard; ///< *second* lock that protects the variable ptrdiff_t offset; ///< offset to the value from global_system_variables on_check_function on_check; @@ -487,5 +487,4 @@ void free_engine_list(plugin_ref *list); plugin_ref *copy_engine_list(plugin_ref *list); plugin_ref *temp_copy_engine_list(THD *thd, plugin_ref *list); char *pretty_print_engine_list(THD *thd, plugin_ref *list); - #endif diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fccf6ef304f..c2a9a99837e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2518,6 +2518,8 @@ bool acl_init(bool dont_read_acl_tables) DBUG_RETURN(1); /* purecov: inspected */ thd->thread_stack= (char*) &thd; thd->store_globals(); + thd->set_query_inner((char*) STRING_WITH_LEN("intern:acl_init"), + default_charset_info); /* It is safe to call acl_reload() since acl_* arrays and hashes which will be freed there are global static objects and thus are initialized @@ -7986,6 +7988,9 @@ bool grant_init() DBUG_RETURN(1); /* purecov: deadcode */ thd->thread_stack= (char*) &thd; thd->store_globals(); + thd->set_query_inner((char*) STRING_WITH_LEN("intern:grant_init"), + default_charset_info); + return_val= grant_reload(thd); delete thd; DBUG_RETURN(return_val); diff --git a/sql/sql_analyze_stmt.h b/sql/sql_analyze_stmt.h index 4136dff1e0c..8f60d4b523a 100644 --- a/sql/sql_analyze_stmt.h +++ b/sql/sql_analyze_stmt.h @@ -414,7 +414,8 @@ public: n_positive_checks++; } - inline void increment_container_elements_count() { container_elements++; } + inline void set_container_elements_count(uint elements) + { container_elements= elements; } uint get_container_elements() const { return container_elements; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 91ab5456875..9634cd4bb48 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4757,6 +4757,7 @@ restart: tbl->reginfo.lock_type= tables->lock_type; tbl->reginfo.skip_locked= tables->skip_locked; } + #ifdef WITH_WSREP /* At this point we have SE associated with table so we can check wsrep_mode diff --git a/sql/sql_base.h b/sql/sql_base.h index c86a652c33a..1b294a468a9 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -357,7 +357,7 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr) } table->tablenr= tablenr; table->map= (table_map) 1 << tablenr; - table->force_index= table_list->force_index; + table->force_index= table->force_index_join= 0; table->force_index_order= table->force_index_group= 0; table->covering_keys= table->s->keys_for_keyread; } diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 02dc8198c7c..61b3df2d086 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -270,13 +270,21 @@ public: { return buffer[0]; } - uint bits_set() + uint bits_set() const { uint res= 0; for (size_t i= 0; i < ARRAY_ELEMENTS; i++) - res += my_count_bits(buffer[i]); + if (buffer[i]) + res+= my_count_bits(buffer[i]); return res; } + uint find_first_bit() const + { + for (size_t i= 0; i < ARRAY_ELEMENTS; i++) + if (buffer[i]) + return (uint)i*BITS_PER_ELEMENT + my_find_first_bit(buffer[i]); + return width; + } class Iterator { const Bitmap& map; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 28119b54ddf..17ce7b3c048 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1235,7 +1235,6 @@ void THD::init() avoid temporary tables replication failure. */ variables.pseudo_thread_id= thread_id; - variables.default_master_connection.str= default_master_connection_buff; ::strmake(default_master_connection_buff, global_system_variables.default_master_connection.str, diff --git a/sql/sql_class.h b/sql/sql_class.h index f0bf695a1c1..ef299e4eb12 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -661,7 +661,7 @@ typedef struct system_variables char* dynamic_variables_ptr; uint dynamic_variables_head; /* largest valid variable offset */ uint dynamic_variables_size; /* how many bytes are in use */ - + ulonglong max_heap_table_size; ulonglong tmp_memory_table_size; ulonglong tmp_disk_table_size; @@ -669,7 +669,6 @@ typedef struct system_variables ulonglong max_statement_time; ulonglong optimizer_switch; ulonglong optimizer_trace; - ulong optimizer_trace_max_mem_size; sql_mode_t sql_mode; ///< which non-standard SQL behaviour should be enabled sql_mode_t old_behavior; ///< which old SQL behaviour should be enabled ulonglong option_bits; ///< OPTION_xxx constants, e.g. OPTION_PROFILING @@ -683,6 +682,7 @@ typedef struct system_variables ulonglong sortbuff_size; ulonglong default_regex_flags; ulonglong max_mem_used; + ulonglong max_rowid_filter_size; /** Place holders to store Multi-source variables in sys_var.cc during @@ -691,10 +691,14 @@ typedef struct system_variables ulonglong slave_skip_counter; ulonglong max_relay_log_size; + double optimizer_where_cost, optimizer_scan_setup_cost; + double long_query_time_double, max_statement_time_double; + double sample_percentage; + ha_rows select_limit; ha_rows max_join_size; ha_rows expensive_subquery_limit; - ulong auto_increment_increment, auto_increment_offset; + #ifdef WITH_WSREP /* Stored values of the auto_increment_increment and auto_increment_offset @@ -703,11 +707,12 @@ typedef struct system_variables original values (which are set by the user) by calculated ones (which are based on the cluster size): */ + ulonglong wsrep_gtid_seq_no; ulong saved_auto_increment_increment, saved_auto_increment_offset; ulong saved_lock_wait_timeout; - ulonglong wsrep_gtid_seq_no; #endif /* WITH_WSREP */ - uint eq_range_index_dive_limit; + + ulong auto_increment_increment, auto_increment_offset; ulong column_compression_zlib_strategy; ulong lock_wait_timeout; ulong join_cache_level; @@ -730,8 +735,8 @@ typedef struct system_variables ulong optimizer_search_depth; ulong optimizer_selectivity_sampling_limit; ulong optimizer_use_condition_selectivity; + ulong optimizer_trace_max_mem_size; ulong use_stat_tables; - double sample_percentage; ulong histogram_size; ulong histogram_type; ulong preload_buff_size; @@ -761,8 +766,16 @@ typedef struct system_variables ulong tx_isolation; ulong updatable_views_with_limit; ulong alter_algorithm; - int max_user_connections; ulong server_id; + ulong session_track_transaction_info; + ulong threadpool_priority; + ulong optimizer_max_sel_arg_weight; + ulong vers_alter_history; + + /* deadlock detection */ + ulong wt_timeout_short, wt_deadlock_search_depth_short; + ulong wt_timeout_long, wt_deadlock_search_depth_long; + /** In slave thread we need to know in behalf of which thread the query is being run to replicate temp tables properly @@ -772,10 +785,18 @@ typedef struct system_variables When replicating an event group with GTID, keep these values around so slave binlog can receive the same GTID as the original. */ - uint32 gtid_domain_id; uint64 gtid_seq_no; + uint32 gtid_domain_id; uint group_concat_max_len; + uint eq_range_index_dive_limit; + uint idle_transaction_timeout; + uint idle_readonly_transaction_timeout; + uint idle_write_transaction_timeout; + uint column_compression_threshold; + uint column_compression_zlib_level; + uint in_subquery_conversion_threshold; + int max_user_connections; /** Default transaction access mode. READ ONLY (true) or READ WRITE (false). @@ -795,7 +816,17 @@ typedef struct system_variables my_bool binlog_annotate_row_events; my_bool binlog_direct_non_trans_update; my_bool column_compression_zlib_wrap; - + my_bool sysdate_is_now; + my_bool wsrep_on; + my_bool wsrep_causal_reads; + my_bool wsrep_dirty_reads; + my_bool pseudo_slave_mode; + my_bool session_track_schema; + my_bool session_track_state_change; +#ifdef USER_VAR_TRACKING + my_bool session_track_user_variables; +#endif // USER_VAR_TRACKING + my_bool tcp_nodelay; plugin_ref table_plugin; plugin_ref tmp_table_plugin; plugin_ref enforced_table_plugin; @@ -821,47 +852,16 @@ typedef struct system_variables MY_LOCALE *lc_time_names; Time_zone *time_zone; + char *session_track_system_variables; - my_bool sysdate_is_now; - - /* deadlock detection */ - ulong wt_timeout_short, wt_deadlock_search_depth_short; - ulong wt_timeout_long, wt_deadlock_search_depth_long; - - my_bool wsrep_on; - my_bool wsrep_causal_reads; - uint wsrep_sync_wait; - ulong wsrep_retry_autocommit; + /* Some wsrep variables */ ulonglong wsrep_trx_fragment_size; + ulong wsrep_retry_autocommit; ulong wsrep_trx_fragment_unit; ulong wsrep_OSU_method; - my_bool wsrep_dirty_reads; - double long_query_time_double, max_statement_time_double; - - my_bool pseudo_slave_mode; - - char *session_track_system_variables; - ulong session_track_transaction_info; - my_bool session_track_schema; - my_bool session_track_state_change; -#ifdef USER_VAR_TRACKING - my_bool session_track_user_variables; -#endif // USER_VAR_TRACKING - my_bool tcp_nodelay; - - ulong threadpool_priority; - - uint idle_transaction_timeout; - uint idle_readonly_transaction_timeout; - uint idle_write_transaction_timeout; - uint column_compression_threshold; - uint column_compression_zlib_level; - uint in_subquery_conversion_threshold; - ulong optimizer_max_sel_arg_weight; - ulonglong max_rowid_filter_size; + uint wsrep_sync_wait; vers_asof_timestamp_t vers_asof_timestamp; - ulong vers_alter_history; my_bool binlog_alter_two_phase; } SV; @@ -952,19 +952,21 @@ typedef struct system_status_var functions are used */ ulong feature_dynamic_columns; /* +1 when creating a dynamic column */ ulong feature_fulltext; /* +1 when MATCH is used */ - ulong feature_gis; /* +1 opening a table with GIS features */ - ulong feature_invisible_columns; /* +1 opening a table with invisible column */ - ulong feature_json; /* +1 when JSON function appears in the statement */ + ulong feature_gis; /* +1 opening table with GIS features */ + ulong feature_invisible_columns; /* +1 opening table with invisible column */ + ulong feature_json; /* +1 when JSON function is used */ ulong feature_locale; /* +1 when LOCALE is set */ ulong feature_subquery; /* +1 when subqueries are used */ - ulong feature_system_versioning; /* +1 opening a table WITH SYSTEM VERSIONING */ + ulong feature_system_versioning; /* +1 opening table WITH SYSTEM VERSIONING */ ulong feature_application_time_periods; /* +1 opening a table with application-time period */ - ulong feature_insert_returning; /* +1 when INSERT...RETURNING is used */ + ulong feature_insert_returning; /* +1 when INSERT...RETURNING is used */ ulong feature_timezone; /* +1 when XPATH is used */ ulong feature_trigger; /* +1 opening a table with triggers */ ulong feature_xml; /* +1 when XPATH is used */ ulong feature_window_functions; /* +1 when window functions are used */ + ulong feature_into_outfile; /* +1 when INTO OUTFILE is used */ + ulong feature_into_variable; /* +1 when INTO VARIABLE is used */ /* From MASTER_GTID_WAIT usage */ ulong master_gtid_wait_timeouts; /* Number of timeouts */ @@ -2669,6 +2671,7 @@ public: struct system_status_var org_status_var; // For user statistics struct system_status_var *initial_status_var; /* used by show status */ THR_LOCK_INFO lock_info; // Locking info of this thread + /** Protects THD data accessed from other threads: - thd->query and thd->query_length (used by SHOW ENGINE @@ -3399,7 +3402,7 @@ public: Check if the number of rows accessed by a statement exceeded LIMIT ROWS EXAMINED. If so, signal the query engine to stop execution. */ - void check_limit_rows_examined() + inline void check_limit_rows_examined() { if (++accessed_rows_and_keys > lex->limit_rows_examined_cnt) set_killed(ABORT_QUERY); @@ -6244,6 +6247,7 @@ public: Item **items_to_copy; /* Fields in tmp table */ TMP_ENGINE_COLUMNDEF *recinfo, *start_recinfo; KEY *keyinfo; + ulong *rec_per_key; ha_rows end_write_records; /** Number of normal fields in the query, including those referred to @@ -6812,13 +6816,13 @@ public: /* Cost to materialize - execute the sub-join and write rows into temp.table */ - Cost_estimate materialization_cost; + double materialization_cost; /* Cost to make one lookup in the temptable */ - Cost_estimate lookup_cost; + double lookup_cost; /* Cost of scanning the materialized table */ - Cost_estimate scan_cost; + double scan_cost; /* --- Execution structures ---------- */ @@ -7407,11 +7411,38 @@ inline void handler::increment_statistics(ulong SSV::*offset) const table->in_use->check_limit_rows_examined(); } +inline void handler::fast_increment_statistics(ulong SSV::*offset) const +{ + status_var_increment(table->in_use->status_var.*offset); +} + inline void handler::decrement_statistics(ulong SSV::*offset) const { status_var_decrement(table->in_use->status_var.*offset); } +/* Update references in the handler to the table */ + +inline void handler::set_table(TABLE* table_arg) +{ + table= table_arg; + costs= &table_arg->s->optimizer_costs; +} + +inline bool handler::pk_is_clustering_key(uint index) const +{ + /* + We have to check for MAX_INDEX as table->s->primary_key can be + MAX_KEY in the case where there is no primary key. + */ + return index != MAX_KEY && is_clustering_key(index); +} + +inline bool handler::is_clustering_key(uint index) const +{ + DBUG_ASSERT(index != MAX_KEY); + return table->is_clustering_key(index); +} inline int handler::ha_ft_read(uchar *buf) { diff --git a/sql/sql_const.h b/sql/sql_const.h index 490b870d768..1e5fef4af36 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -119,8 +119,13 @@ #define CREATE_MODE 0 /* Default mode on new files */ #define NAMES_SEP_CHAR 255 /* Char to sep. names */ -#define READ_RECORD_BUFFER (uint) (IO_SIZE*8) /* Pointer_buffer_size */ -#define DISK_BUFFER_SIZE (uint) (IO_SIZE*16) /* Size of diskbuffer */ +/* + This is used when reading large blocks, sequential read. + We assume that reading this much will be roughly the same cost as 1 + seek / fetching one row from the storage engine. + Cost of one read of DISK_CHUNK_SIZE is DISK_SEEK_BASE_COST (ms). +*/ +#define DISK_CHUNK_SIZE (uint) (65536) /* Size of diskbuffer for tmpfiles */ #define FRM_VER_TRUE_VARCHAR (FRM_VER+4) /* 10 */ #define FRM_VER_EXPRESSSIONS (FRM_VER+5) /* 11 */ @@ -199,63 +204,19 @@ #define MIN_ROWS_TO_USE_TABLE_CACHE 100 #define MIN_ROWS_TO_USE_BULK_INSERT 100 -/** - The following is used to decide if MySQL should use table scanning - instead of reading with keys. The number says how many evaluation of the - WHERE clause is comparable to reading one extra row from a table. -*/ -#define TIME_FOR_COMPARE 5.0 // 5 WHERE compares == one read -#define TIME_FOR_COMPARE_IDX 20.0 - -#define IDX_BLOCK_COPY_COST ((double) 1 / TIME_FOR_COMPARE) -#define IDX_LOOKUP_COST ((double) 1 / 8) -#define MULTI_RANGE_READ_SETUP_COST (IDX_BLOCK_COPY_COST/10) - -/** - Number of comparisons of table rowids equivalent to reading one row from a - table. -*/ -#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*100) - -/* cost1 is better that cost2 only if cost1 + COST_EPS < cost2 */ -#define COST_EPS 0.001 - /* - For sequential disk seeks the cost formula is: - DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST * #blocks_to_skip - - The cost of average seek - DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST*BLOCKS_IN_AVG_SEEK =1.0. + The lower bound of accepted rows when using filter. + This is used to ensure that filters are not too agressive. */ -#define DISK_SEEK_BASE_COST ((double)0.9) - -#define BLOCKS_IN_AVG_SEEK 128 - -#define DISK_SEEK_PROP_COST ((double)0.1/BLOCKS_IN_AVG_SEEK) - +#define MIN_ROWS_AFTER_FILTERING 1.0 /** - Number of rows in a reference table when refereed through a not unique key. + Number of rows in a reference table when refered through a not unique key. This value is only used when we don't know anything about the key distribution. */ #define MATCHING_ROWS_IN_OTHER_TABLE 10 -/* - Subquery materialization-related constants -*/ -#define HEAP_TEMPTABLE_LOOKUP_COST 0.05 -#define DISK_TEMPTABLE_LOOKUP_COST 1.0 -#define SORT_INDEX_CMP_COST 0.02 - - -#define COST_MAX (DBL_MAX * (1.0 - DBL_EPSILON)) - -#define COST_ADD(c,d) (COST_MAX - (d) > (c) ? (c) + (d) : COST_MAX) - -#define COST_MULT(c,f) (COST_MAX / (f) > (c) ? (c) * (f) : COST_MAX) - - #define MY_CHARSET_BIN_MB_MAXLEN 1 /** Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used). */ diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index d31d0b949ba..0c0f05aab07 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -526,7 +526,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, select=make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); if (unlikely(error)) DBUG_RETURN(TRUE); - if ((select && select->check_quick(thd, safe_update, limit)) || !limit) + if (unlikely((select && select->check_quick(thd, safe_update, limit)) || + table->stat_records() == 0 || + !limit)) { query_plan.set_impossible_where(); if (thd->lex->describe || thd->lex->analyze_stmt) diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 6f0857239dd..1fa5179875c 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -870,18 +870,20 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) goto exit; /* - Temp table is created so that it hounours if UNION without ALL is to be + Temp table is created so that it honors if UNION without ALL is to be processed - As 'distinct' parameter we always pass FALSE (0), because underlying - query will control distinct condition by itself. Correct test of - distinct underlying query will be is_unit_op && + As 'distinct' parameter we pass unit->distinct, which tells us if + the values should be uniq. + Note that the underlying query will also control distinct condition. + Correct test of distinct underlying query will be is_unit_op && !unit->union_distinct->next_select() (i.e. it is union and last distinct SELECT is last SELECT of UNION). */ thd->create_tmp_table_for_derived= TRUE; if (!(derived->table) && - derived->derived_result->create_result_table(thd, &unit->types, FALSE, + derived->derived_result->create_result_table(thd, &unit->types, + unit->distinct, (first_select->options | thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS), diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 7c3e87d42e3..5cfe3082b35 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -1033,6 +1033,9 @@ void Explain_select::print_explain_json(Explain_query *query, writer->add_member("select_id").add_ll(select_id); add_linkage(writer); + if (cost != 0.0) + writer->add_member("cost").add_double(cost); + if (is_analyze && time_tracker.get_loops()) { writer->add_member("r_loops").add_ll(time_tracker.get_loops()); @@ -1379,10 +1382,12 @@ double Explain_table_access::get_r_filtered() } -int Explain_table_access::print_explain(select_result_sink *output, uint8 explain_flags, +int Explain_table_access::print_explain(select_result_sink *output, + uint8 explain_flags, bool is_analyze, uint select_id, const char *select_type, - bool using_temporary, bool using_filesort) + bool using_temporary, + bool using_filesort) { THD *thd= output->thd; // note: for SHOW EXPLAIN, this is target thd. MEM_ROOT *mem_root= thd->mem_root; @@ -1911,6 +1916,9 @@ void Explain_table_access::print_explain_json(Explain_query *query, rowid_filter->print_explain_json(query, writer, is_analyze); } + if (loops != 0.0) + writer->add_member("loops").add_double(loops); + /* r_loops (not present in tabular output) */ if (is_analyze) { @@ -1940,7 +1948,13 @@ void Explain_table_access::print_explain_json(Explain_query *query, else writer->add_null(); } + } + if (cost != 0.0) + writer->add_member("cost").add_double(cost); + + if (is_analyze) + { if (op_tracker.get_loops()) { double total_time= op_tracker.get_time_ms(); @@ -2011,6 +2025,9 @@ void Explain_table_access::print_explain_json(Explain_query *query, writer->add_double(jbuf_tracker.get_filtered_after_where()*100.0); else writer->add_null(); + + writer->add_member("r_unpack_time_ms"); + writer->add_double(jbuf_unpack_tracker.get_time_ms()); } } diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 38c5c3e6595..67abfe2e9da 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -216,6 +216,7 @@ public: message(NULL), having(NULL), having_value(Item::COND_UNDEF), using_temporary(false), using_filesort(false), + cost(0.0), time_tracker(is_analyze), aggr_tree(NULL) {} @@ -249,9 +250,10 @@ public: bool using_temporary; bool using_filesort; + double cost; /* ANALYZE members */ Time_and_counter_tracker time_tracker; - + /* Part of query plan describing sorting, temp.table usage, and duplicate removal @@ -753,9 +755,11 @@ public: class Explain_table_access : public Sql_alloc { public: - Explain_table_access(MEM_ROOT *root) : + Explain_table_access(MEM_ROOT *root, bool timed) : derived_select_number(0), non_merged_sjm_number(0), + cost(0.0), + loops(0.0), extra_tags(root), range_checked_fer(NULL), full_scan_on_null_key(false), @@ -766,6 +770,7 @@ public: pushed_index_cond(NULL), sjm_nest(NULL), pre_join_sort(NULL), + jbuf_unpack_tracker(timed), rowid_filter(NULL) {} ~Explain_table_access() { delete sjm_nest; } @@ -823,6 +828,10 @@ public: ha_rows rows; double filtered; + /* Total cost incurred during one execution of this select */ + double cost; + + double loops; /* Contents of the 'Extra' column. Some are converted into strings, some have parameters, values for which are stored below. @@ -874,6 +883,7 @@ public: Gap_time_tracker extra_time_tracker; Table_access_tracker jbuf_tracker; + Time_and_counter_tracker jbuf_unpack_tracker; Explain_rowid_filter *rowid_filter; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 7235dc6472d..bd7f04d2ce8 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -674,7 +674,7 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, if ((c_key->flags & HA_SPATIAL) || c_key->algorithm == HA_KEY_ALG_FULLTEXT || (ha_rkey_mode != HA_READ_KEY_EXACT && - (table->file->index_flags(handler->keyno, 0, TRUE) & + (table->key_info[handler->keyno].index_flags & (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE)) == 0)) { my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), @@ -690,8 +690,7 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, } if (key_expr->elements < keyinfo->user_defined_key_parts && - (table->file->index_flags(handler->keyno, 0, TRUE) & - HA_ONLY_WHOLE_INDEX)) + (table->key_info[handler->keyno].index_flags & HA_ONLY_WHOLE_INDEX)) { my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), table->file->index_type(handler->keyno), keyinfo->name.str); diff --git a/sql/sql_help.cc b/sql/sql_help.cc index f9932f11798..51fdd58b9c4 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -664,16 +664,19 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, /* Assume that no indexes cover all required fields */ table->covering_keys.clear_all(); + table->file->info(HA_STATUS_VARIABLE); + table->used_stat_records= table->file->stats.records; SQL_SELECT *res= make_select(table, 0, 0, cond, 0, 0, error); - if (unlikely(*error) || - (likely(res) && unlikely(res->check_quick(thd, 0, HA_POS_ERROR))) || - (likely(res) && res->quick && unlikely(res->quick->reset()))) - { - delete res; - res=0; - } - return res; + if (unlikely(!res) || unlikely(*error)) + goto error; + (void) res->check_quick(thd, 0, HA_POS_ERROR); + if (!res->quick || res->quick->reset() == 0) + return res; + +error: + delete res; + return 0; } /* @@ -1076,7 +1079,9 @@ error: new_trans.restore_old_transaction(); error2: - DBUG_RETURN(TRUE); + if (!thd->is_error()) + my_eof(thd); + DBUG_RETURN(thd->is_error()); } diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index c7b6a0bf6e4..3c19674ff96 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -910,7 +910,12 @@ int JOIN_CACHE::alloc_buffer() min_buff_size= get_min_join_buffer_size(); buff_size= get_max_join_buffer_size(optimize_buff_size); - for (tab= start_tab; tab!= join_tab; + /* + Compute the total buffer usage for all join buffers up to + and including the current one. + */ + for (tab= first_linear_tab(join, WITHOUT_BUSH_ROOTS, WITHOUT_CONST_TABLES); + tab != join_tab; tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS)) { cache= tab->cache; @@ -1080,7 +1085,7 @@ int JOIN_CACHE::init(bool for_explain) /* - Check the possibility to read the access keys directly from the join buffer + Check the possibility to read the access keys directly from the join buffer SYNOPSIS check_emb_key_usage() @@ -1600,6 +1605,7 @@ bool JOIN_CACHE::put_record() bool JOIN_CACHE::get_record() { bool res; + ANALYZE_START_TRACKING(thd(), join_tab->jbuf_unpack_tracker); uchar *prev_rec_ptr= 0; if (with_length) pos+= size_of_rec_len; @@ -1615,6 +1621,7 @@ bool JOIN_CACHE::get_record() if (prev_cache) prev_cache->get_record_by_pos(prev_rec_ptr); } + ANALYZE_STOP_TRACKING(thd(), join_tab->jbuf_unpack_tracker); return res; } @@ -2144,12 +2151,12 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last) if (!join_tab->first_unmatched) { - bool pfs_batch_update= join_tab->pfs_batch_update(join); - if (pfs_batch_update) + DBUG_ASSERT(join_tab->cached_pfs_batch_update == join_tab->pfs_batch_update()); + if (join_tab->cached_pfs_batch_update) join_tab->table->file->start_psi_batch_mode(); /* Find all records from join_tab that match records from join buffer */ rc= join_matching_records(skip_last); - if (pfs_batch_update) + if (join_tab->cached_pfs_batch_update) join_tab->table->file->end_psi_batch_mode(); if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) goto finish; @@ -2319,7 +2326,8 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last) if ((rc= join_tab_execution_startup(join_tab)) < 0) goto finish2; - join_tab->build_range_rowid_filter_if_needed(); + if (join_tab->need_to_build_rowid_filter) + join_tab->build_range_rowid_filter(); /* Prepare to retrieve all records of the joined table */ if (unlikely((error= join_tab_scan->open()))) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e3f486486d7..5e85d1d0902 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2873,7 +2873,7 @@ void st_select_lex_node::init_query_common() { options= 0; set_linkage(UNSPECIFIED_TYPE); - distinct= TRUE; + distinct= FALSE; no_table_names_allowed= 0; uncacheable= 0; } @@ -5956,7 +5956,7 @@ unit_common_op st_select_lex_unit::common_op() else { if (operation != op) - operation= OP_MIX; + return OP_MIX; } } } @@ -5966,12 +5966,13 @@ unit_common_op st_select_lex_unit::common_op() Save explain structures of a UNION. The only variable member is whether the union has "Using filesort". - There is also save_union_explain_part2() function, which is called before we read - UNION's output. + There is also save_union_explain_part2() function, which is called before we + read UNION's output. The reason for it is examples like this: - SELECT col1 FROM t1 UNION SELECT col2 FROM t2 ORDER BY (select ... from t3 ...) + SELECT col1 FROM t1 UNION SELECT col2 FROM t2 + ORDER BY (select ... from t3 ...) Here, the (select ... from t3 ...) subquery must be a child of UNION's st_select_lex. However, it is not connected as child until a very late @@ -10145,6 +10146,7 @@ SELECT_LEX_UNIT *LEX::parsed_select_expr_start(SELECT_LEX *s1, SELECT_LEX *s2, if (res == NULL) return NULL; res->pre_last_parse= sel1; + res->distinct= distinct; push_select(res->fake_select_lex); return res; } @@ -10191,7 +10193,7 @@ SELECT_LEX_UNIT *LEX::parsed_select_expr_cont(SELECT_LEX_UNIT *unit, /** Add primary expression as the next term in a given query expression body - pruducing a new query expression body + producing a new query expression body */ SELECT_LEX_UNIT * @@ -10391,7 +10393,6 @@ bool LEX::parsed_TVC_start() insert_list= 0; if (!(sel= alloc_select(TRUE)) || push_select(sel)) return true; - sel->init_select(); sel->braces= FALSE; // just initialisation return false; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 48c3147a95c..579e4cd27f7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -8214,8 +8214,6 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->mdl_type= mdl_type; ptr->table_options= table_options; ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING); - /* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */ - ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX); ptr->ignore_leaves= MY_TEST(table_options & TL_OPTION_IGNORE_LEAVES); ptr->sequence= MY_TEST(table_options & TL_OPTION_SEQUENCE); ptr->derived= table->sel; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index a47fefc13f6..f8b4948a3ac 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1830,6 +1830,7 @@ static bool register_builtin(struct st_maria_plugin *plugin, /* called only by plugin_init() */ + static void plugin_load(MEM_ROOT *tmp_root) { TABLE_LIST tables; @@ -1847,6 +1848,8 @@ static void plugin_load(MEM_ROOT *tmp_root) new_thd->thread_stack= (char*) &tables; new_thd->store_globals(); + new_thd->set_query_inner((char*) STRING_WITH_LEN("intern:plugin_load"), + default_charset_info); new_thd->db= MYSQL_SCHEMA_NAME; bzero((char*) &new_thd->net, sizeof(new_thd->net)); tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PLUGIN_NAME, 0, TL_READ); diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 8f0f15a982a..8104806af71 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -83,6 +83,8 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, { thd->thread_stack= (char*) &tmp_thd; thd->store_globals(); + thd->set_query_inner((char*) STRING_WITH_LEN("intern:reload_acl"), + default_charset_info); } if (likely(thd)) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9b9d93d182e..a88b8a54a08 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -47,6 +47,7 @@ // print_sjm, print_plan, TEST_join #include "records.h" // init_read_record, end_read_record #include "filesort.h" // filesort_free_buffers +#include "filesort_utils.h" // get_qsort_sort_cost #include "sql_union.h" // mysql_union #include "opt_subselect.h" #include "sql_derived.h" @@ -69,6 +70,7 @@ #include "opt_trace.h" #include "derived_handler.h" #include "create_tmp_table.h" +#include "optimizer_defaults.h" /* A key part number that means we're using a fulltext scan. @@ -83,6 +85,30 @@ */ #define FT_KEYPART (MAX_FIELDS+10) +/* + We assume that when we do hash join, only 10 % rows in the hash will + match the current found row. +*/ +#define HASH_FANOUT 0.1 + +/* + The following is used to check that A <= B, but with some margin as the + calculation is done slightly differently (mathematically correct, but + double calculations are not exact). + This is only used when comparing read rows and output rows, which + means that we can assume that both values are >= 0 and B cannot be notable + smaller than A. +*/ + +#define crash_if_first_double_is_bigger(A,B) DBUG_ASSERT(((A) == 0.0 && (B) == 0.0) || (A)/(B) < 1.0000001) + +#define double_to_rows(A) ((A) >= ((double)HA_ROWS_MAX) ? HA_ROWS_MAX : (ha_rows) (A)) + +inline double safe_filtered(double a, double b) +{ + return b != 0 ? a/b*100.0 : 0.0; +} + const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", "MAYBE_REF","ALL","range","index","fulltext", "ref_or_null","unique_subquery","index_subquery", @@ -232,7 +258,6 @@ static COND *make_cond_for_table_from_pred(THD *thd, Item *root_cond, bool is_top_and_level); static Item* part_of_refkey(TABLE *form,Field *field); -uint find_shortest_key(TABLE *table, const key_map *usable_keys); static bool test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, key_map usable_keys, int key, @@ -305,8 +330,9 @@ static JOIN_TAB *next_breadth_first_tab(JOIN_TAB *first_top_tab, static bool find_order_in_list(THD *, Ref_ptr_array, TABLE_LIST *, ORDER *, List &, List &, bool, bool, bool); -static double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, - table_map rem_tables); +static double table_after_join_selectivity(JOIN *join, uint idx, JOIN_TAB *s, + table_map rem_tables, + double *records_out); void set_postjoin_aggr_write_func(JOIN_TAB *tab); static Item **get_sargable_cond(JOIN *join, TABLE *table); @@ -408,9 +434,10 @@ bool dbug_user_var_equals_str(THD *thd, const char *name, const char* value) POSITION::POSITION() { table= 0; - records_read= cond_selectivity= read_time= 0.0; + records_read= cond_selectivity= read_time= records_out= records_init= 0.0; prefix_record_count= 0.0; key= 0; + forced_index= 0; use_join_buffer= 0; sj_strategy= SJ_OPT_NONE; n_sj_tables= 0; @@ -507,7 +534,6 @@ void JOIN::init(THD *thd_arg, List &fields_arg, no_const_tables= FALSE; first_select= sub_select; - set_group_rpa= false; group_sent= 0; outer_ref_cond= pseudo_bits_cond= NULL; @@ -532,9 +558,10 @@ static void trace_table_dependencies(THD *thd, { TABLE_LIST *table_ref= join_tabs[i].tab_list; Json_writer_object trace_one_table(thd); - trace_one_table.add_table_name(&join_tabs[i]); - trace_one_table.add("row_may_be_null", - (bool)table_ref->table->maybe_null); + trace_one_table. + add_table_name(&join_tabs[i]). + add("row_may_be_null", + (bool)table_ref->table->maybe_null); const table_map map= table_ref->get_map(); DBUG_ASSERT(map < (1ULL << table_count)); for (uint j= 0; j < table_count; j++) @@ -1736,7 +1763,7 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num, } } - if (thd->trace_started()) + if (unlikely(thd->trace_started())) { Json_writer_object trace_wrapper(thd); opt_trace_print_expanded_query(thd, select_lex, &trace_wrapper); @@ -1876,6 +1903,13 @@ int JOIN::optimize() res= build_explain(); optimization_state= JOIN::OPTIMIZATION_DONE; } + + /* + Store the cost of this query into a user variable + TODO: calculate a correct cost for a query with subqueries and UNIONs. + */ + if (select_lex->select_number == 1) + thd->status_var.last_query_cost= best_read; return res; } @@ -1917,9 +1951,9 @@ bool JOIN::make_range_rowid_filters() continue; DBUG_ASSERT(!(tab->ref.key >= 0 && - tab->ref.key == (int) tab->range_rowid_filter_info->key_no)); + tab->ref.key == (int) tab->range_rowid_filter_info->get_key_no())); DBUG_ASSERT(!(tab->ref.key == -1 && tab->quick && - tab->quick->index == tab->range_rowid_filter_info->key_no)); + tab->quick->index == tab->range_rowid_filter_info->get_key_no())); int err; SQL_SELECT *sel= NULL; @@ -1932,14 +1966,11 @@ bool JOIN::make_range_rowid_filters() key_map filter_map; filter_map.clear_all(); - filter_map.set_bit(tab->range_rowid_filter_info->key_no); + filter_map.set_bit(tab->range_rowid_filter_info->get_key_no()); filter_map.merge(tab->table->with_impossible_ranges); - bool force_index_save= tab->table->force_index; - tab->table->force_index= true; int rc= sel->test_quick_select(thd, filter_map, (table_map) 0, (ha_rows) HA_POS_ERROR, - true, false, true, true); - tab->table->force_index= force_index_save; + true /* force index */, false, true, true); if (thd->is_error()) goto no_filter; /* @@ -1962,7 +1993,10 @@ bool JOIN::make_range_rowid_filters() tab->range_rowid_filter_info, filter_container, sel); if (tab->rowid_filter) + { + tab->need_to_build_rowid_filter= true; continue; + } } no_filter: if (sel->quick) @@ -1990,24 +2024,23 @@ bool JOIN::make_range_rowid_filters() bool JOIN::init_range_rowid_filters() { - DBUG_ENTER("init_range_rowid_filters"); - JOIN_TAB *tab; + DBUG_ENTER("init_range_rowid_filters"); for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) { + tab->need_to_build_rowid_filter= false; // Safety if (!tab->rowid_filter) continue; if (tab->rowid_filter->get_container()->alloc()) { - delete tab->rowid_filter; - tab->rowid_filter= 0; + tab->clear_range_rowid_filter(); continue; } tab->table->file->rowid_filter_push(tab->rowid_filter); - tab->is_rowid_filter_built= false; + tab->need_to_build_rowid_filter= true; } DBUG_RETURN(0); } @@ -2029,6 +2062,7 @@ JOIN::optimize_inner() { DBUG_ENTER("JOIN::optimize_inner"); subq_exit_fl= false; + best_read= 0.0; DEBUG_SYNC(thd, "before_join_optimize"); THD_STAGE_INFO(thd, stage_optimizing); @@ -2248,7 +2282,8 @@ JOIN::optimize_inner() (see build_equal_items() below) because it can be not rebuilt at second invocation. */ - if (!thd->stmt_arena->is_conventional() && thd->mem_root != thd->stmt_arena->mem_root) + if (!thd->stmt_arena->is_conventional() && + thd->mem_root != thd->stmt_arena->mem_root) for (TABLE_LIST *tbl= tables_list; tbl; tbl= tbl->next_local) if (tbl->table && tbl->on_expr && tbl->table->versioned()) { @@ -2587,8 +2622,12 @@ int JOIN::optimize_stage2() if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) DBUG_RETURN(1); - if (optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_WITH_KEYS)) - drop_unused_derived_keys(); + /* + We have to call drop_unused_derived_keys() even if we don't have any + generated keys (enabled with OPTIMIZER_SWITCH_DERIVED_WITH_KEYS) + as we may still have unique constraints we have to get rid of. + */ + drop_unused_derived_keys(); if (rollup.state != ROLLUP::STATE_NONE) { @@ -2621,7 +2660,7 @@ int JOIN::optimize_stage2() goto setup_subq_exit; } if (!(thd->variables.option_bits & OPTION_BIG_SELECTS) && - best_read > (double) thd->variables.max_join_size && + join_record_count > (double) thd->variables.max_join_size && !(select_options & SELECT_DESCRIBE)) { /* purecov: inspected */ my_message(ER_TOO_BIG_SELECT, ER_THD(thd, ER_TOO_BIG_SELECT), MYF(0)); @@ -3188,6 +3227,8 @@ int JOIN::optimize_stage2() */ if ((order || group_list) && tab->type != JT_ALL && + tab->type != JT_RANGE && + tab->type != JT_NEXT && tab->type != JT_FT && tab->type != JT_REF_OR_NULL && ((order && simple_order) || (group_list && simple_group))) @@ -3569,7 +3610,7 @@ bool JOIN::make_aggr_tables_info() TABLE* table= create_tmp_table(thd, curr_tab->tmp_table_param, all_fields, NULL, distinct, - TRUE, select_options, HA_POS_ERROR, + TRUE, select_options, HA_ROWS_MAX, &empty_clex_str, !need_tmp, keep_row_order); if (!table) @@ -4047,7 +4088,14 @@ bool JOIN::make_aggr_tables_info() */ if (unit->lim.is_with_ties()) { - if (alloc_order_fields(this, order, with_ties_order_count)) + /* + When ORDER BY is eliminated, we make use of the GROUP BY list. + We've already counted how many elements from ORDER BY + must be evaluated as part of WITH TIES so we use that. + */ + ORDER *order_src = order ? order : group_list; + if (alloc_order_fields(this, order_src, + with_ties_order_count)) DBUG_RETURN(true); } @@ -4214,14 +4262,13 @@ bool JOIN::add_sorting_to_table(JOIN_TAB *tab, ORDER *order) { tab->filesort= - new (thd->mem_root) Filesort(order, HA_POS_ERROR, tab->keep_current_rowid, + new (thd->mem_root) Filesort(order, HA_ROWS_MAX, tab->keep_current_rowid, tab->select); if (!tab->filesort) return true; TABLE *table= tab->table; if ((tab == join_tab + const_tables) && - table->pos_in_table_list && table->pos_in_table_list->is_sjm_scan_table()) { tab->filesort->set_all_read_bits= TRUE; @@ -4396,6 +4443,15 @@ bool JOIN::shrink_join_buffers(JOIN_TAB *jt, } buff_size= cache->get_join_buffer_size(); curr_space-= buff_size; + if (needed_space < buff_size) + { + /* + Safety: fail if we've exhausted available buffer space with + reduced join buffers. + */ + DBUG_ASSERT(0); + return TRUE; + } needed_space-= buff_size; } } @@ -4437,7 +4493,6 @@ JOIN::reinit() if (current_ref_ptrs != items0) { set_items_ref_array(items0); - set_group_rpa= false; } /* need to reset ref access state (see join_read_key) */ @@ -5252,7 +5307,6 @@ make_join_statistics(JOIN *join, List &tables_list, DYNAMIC_ARRAY *keyuse_array) { int error= 0; - TABLE *UNINIT_VAR(table); /* inited in all loops */ uint i,table_count,const_count,key; uint sort_space; table_map found_const_table_map, all_table_map; @@ -5313,11 +5367,13 @@ make_join_statistics(JOIN *join, List &tables_list, for (s= stat, i= 0; (tables= ti++); s++, i++) { TABLE_LIST *embedding= tables->embedding; + TABLE *table= tables->table; stat_vector[i]=s; - table_vector[i]=s->table=table=tables->table; + table_vector[i]= s->table= table; s->tab_list= tables; table->pos_in_table_list= tables; error= tables->fetch_number_of_rows(); + /* Calculate table->use_stat_records */ set_statistics_for_table(join->thd, table); bitmap_clear_all(&table->cond_set); @@ -5345,7 +5401,14 @@ make_join_statistics(JOIN *join, List &tables_list, s->dependent= tables->dep_tables; if (tables->schema_table) - table->file->stats.records= table->used_stat_records= 2; + { + /* + Information schema is slow and we don't know how many rows we will + find. Be setting a moderate ammount of rows we are more likely + to have it materialized if needed. + */ + table->file->stats.records= table->used_stat_records= 100; + } table->opt_range_condition_rows= table->stat_records(); s->on_expr_ref= &tables->on_expr; @@ -5413,6 +5476,7 @@ make_join_statistics(JOIN *join, List &tables_list, { set_position(join,const_count++,s,(KEYUSE*) 0); no_rows_const_tables |= table->map; + table->file->stats.records= 0; } } @@ -5446,7 +5510,7 @@ make_join_statistics(JOIN *join, List &tables_list, for (s= stat ; s < stat_end ; s++) { - table= s->table; + TABLE *table= s->table; for (JOIN_TAB *t= stat ; t < stat_end ; t++) { if (t->dependent & table->map) @@ -5480,7 +5544,7 @@ make_join_statistics(JOIN *join, List &tables_list, } } - if (thd->trace_started()) + if (unlikely(thd->trace_started())) trace_table_dependencies(thd, stat, join->table_count); if (join->conds || outer_join) @@ -5501,7 +5565,7 @@ make_join_statistics(JOIN *join, List &tables_list, skip_unprefixed_keyparts)) goto error; DBUG_EXECUTE("opt", print_keyuse_array(keyuse_array);); - if (thd->trace_started()) + if (unlikely(thd->trace_started())) print_keyuse_array_for_trace(thd, keyuse_array); } @@ -5550,7 +5614,7 @@ make_join_statistics(JOIN *join, List &tables_list, for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++) { - table=s->table; + TABLE *table= s->table; if (table->is_filled_at_execution()) continue; @@ -5603,10 +5667,11 @@ make_join_statistics(JOIN *join, List &tables_list, (*s->on_expr_ref)->is_expensive())) { // system table int tmp= 0; - s->type=JT_SYSTEM; + s->type= JT_SYSTEM; join->const_table_map|=table->map; set_position(join,const_count++,s,(KEYUSE*) 0); - if ((tmp= join_read_const_table(join->thd, s, join->positions+const_count-1))) + if ((tmp= join_read_const_table(join->thd, s, + join->positions+const_count-1))) { if (tmp > 0) goto error; // Fatal error @@ -5670,7 +5735,14 @@ make_join_statistics(JOIN *join, List &tables_list, base_const_ref.intersect(base_part); base_eq_part= eq_part; base_eq_part.intersect(base_part); - if (table->actual_key_flags(keyinfo) & HA_NOSAME) + + /* + We can read the const record if we are using a full unique key and + if the table is not an unopened to be materialized table/view. + */ + if ((table->actual_key_flags(keyinfo) & HA_NOSAME) && + (!s->table->pos_in_table_list->is_materialized_derived() || + s->table->pos_in_table_list->fill_me)) { if (base_const_ref == base_eq_part && @@ -5798,52 +5870,43 @@ make_join_statistics(JOIN *join, List &tables_list, s->startup_cost= 0; if (s->type == JT_SYSTEM || s->type == JT_CONST) { - Json_writer_object table_records(thd); - /* Only one matching row */ - s->found_records= s->records= 1; + ha_rows records= 1; + if (s->type == JT_SYSTEM || s->table->file->stats.records == 0) + records= s->table->file->stats.records; + /* zero or one matching row */ + s->records= s->found_records= records; + s->records_init= s->records_out= rows2double(records); s->read_time=1.0; - s->worst_seeks=1.0; - table_records.add_table_name(s) - .add("rows", s->found_records) - .add("cost", s->read_time) - .add("table_type", s->type == JT_CONST ? - "const" : - "system"); + table_records.add_table_name(s). + add("rows", s->found_records). + add("cost", s->read_time). + add("table_type", s->type == JT_CONST ? + "const" : "system"); continue; } - /* Approximate found rows and time to read them */ - if (s->table->is_filled_at_execution()) - { - get_delayed_table_estimates(s->table, &s->records, &s->read_time, - &s->startup_cost); - s->found_records= s->records; - table->opt_range_condition_rows=s->records; - } - else - s->scan_time(); + /* + Approximate found rows and time to read them + Update found_records, records, read_time and other scan related + variables + */ + s->estimate_scan_time(); if (s->table->is_splittable()) s->add_keyuses_for_splitting(); - /* - Set a max range of how many seeks we can expect when using keys - This is can't be to high as otherwise we are likely to use - table scan. - */ - s->worst_seeks= MY_MIN((double) s->found_records / 10, - (double) s->read_time*3); - if (s->worst_seeks < 2.0) // Fix for small tables - s->worst_seeks=2.0; - /* Add to stat->const_keys those indexes for which all group fields or all select distinct fields participate in one index. */ add_group_and_distinct_keys(join, s); - s->table->cond_selectivity= 1.0; - + /* This will be updated in calculate_cond_selectivity_for_table() */ + s->table->set_cond_selectivity(1.0); + DBUG_ASSERT(s->table->used_stat_records == 0 || + s->table->cond_selectivity <= + s->table->opt_range_condition_rows / + s->table->used_stat_records); /* Perform range analysis if there are keys it could use (1). Don't do range analysis for materialized subqueries (2). @@ -5856,7 +5919,7 @@ make_join_statistics(JOIN *join, List &tables_list, s->table->pos_in_table_list->is_materialized_derived())) // (3) { bool impossible_range= FALSE; - ha_rows records= HA_POS_ERROR; + ha_rows records= HA_ROWS_MAX; SQL_SELECT *select= 0; Item **sargable_cond= NULL; if (!s->const_keys.is_clear_all()) @@ -5923,6 +5986,7 @@ make_join_statistics(JOIN *join, List &tables_list, } else { + double records= 1; join->const_table_map|= s->table->map; set_position(join,const_count++,s,(KEYUSE*) 0); s->type= JT_CONST; @@ -5933,7 +5997,10 @@ make_join_statistics(JOIN *join, List &tables_list, s->info= ET_IMPOSSIBLE_ON_CONDITION; found_const_table_map|= s->table->map; mark_as_null_row(s->table); // All fields are NULL + records= 0; } + s->records_init= s->records_out= records; + s->found_records= s->records= (ha_rows)records; } } if (records != HA_POS_ERROR) @@ -5945,13 +6012,13 @@ make_join_statistics(JOIN *join, List &tables_list, delete select; else { - if (thd->trace_started()) + if (unlikely(thd->trace_started())) add_table_scan_values_to_trace(thd, s); } } else { - if (thd->trace_started()) + if (unlikely(thd->trace_started())) add_table_scan_values_to_trace(thd, s); } } @@ -5987,13 +6054,12 @@ make_join_statistics(JOIN *join, List &tables_list, DBUG_RETURN(TRUE); /* purecov: inspected */ { - double records= 1; SELECT_LEX_UNIT *unit= join->select_lex->master_unit(); /* Find an optimal join order of the non-constant tables. */ if (join->const_tables != join->table_count) { - if (choose_plan(join, all_table_map & ~join->const_table_map)) + if (choose_plan(join, all_table_map & ~join->const_table_map, 0)) goto error; #ifdef HAVE_valgrind @@ -6008,7 +6074,8 @@ make_join_statistics(JOIN *join, List &tables_list, memcpy((uchar*) join->best_positions,(uchar*) join->positions, sizeof(POSITION)*join->const_tables); join->join_record_count= 1.0; - join->best_read=1.0; + /* Const tables are part of optimizer setup and not counted in cost */ + join->best_read=0.0; } if (!(join->select_options & SELECT_DESCRIBE) && @@ -6018,10 +6085,12 @@ make_join_statistics(JOIN *join, List &tables_list, Calculate estimated number of rows for materialized derived table/view. */ + double records= 1.0; + ha_rows rows; for (i= 0; i < join->table_count ; i++) if (double rr= join->best_positions[i].records_read) records= COST_MULT(records, rr); - ha_rows rows= records > (double) HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records; + rows= double_to_rows(records); set_if_smaller(rows, unit->lim.get_select_limit()); join->select_lex->increase_derived_records(rows); } @@ -6369,8 +6438,8 @@ add_key_field(JOIN *join, Field op formula Field IS NULL Field IS NOT NULL - Field BETWEEN ... - Field IN ... + Field BETWEEN ... + Field IN ... */ if (field->flags & PART_KEY_FLAG) { @@ -6458,10 +6527,10 @@ add_key_field(JOIN *join, @param field_item Field item used for comparison @param eq_func True if we used =, <=> or IS NULL @param value Value used for comparison with field_item - @param num_values Number of values[] that we are comparing against + @param num_values Number of values[] that we are comparing against @param usable_tables Tables which can be used for key optimization @param sargables IN/OUT Array of found sargable candidates - @param row_col_no if = n that > 0 then field is compared only + @param row_col_no if = n that > 0 then field is compared only against the n-th component of row values @note @@ -7333,6 +7402,10 @@ static void remember_if_eq_ref_key(JOIN *join, KEYUSE *use) Special treatment for ft-keys. Update join->eq_ref_tables with a bitmap of all tables that can possible have a EQ_REF key. + + Note that the keys are generated to be used by best_access_path() during + the optimization stage. Unused keys will later be deleted by + JOIN::drop_unused_derived_keys(). */ bool sort_and_filter_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse, @@ -7382,7 +7455,9 @@ bool sort_and_filter_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse, } else { - /* Key changed, check if previous key was a primary/unique key lookup */ + /* + Key changed, check if previous key was a primary/unique key lookup + */ if (prev != &key_end && !found_unprefixed_key_part) remember_if_eq_ref_key(join, prev); found_unprefixed_key_part= 0; @@ -7663,7 +7738,9 @@ void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key) { join->positions[idx].table= table; join->positions[idx].key=key; - join->positions[idx].records_read=1.0; /* This is a const table */ + join->positions[idx].records_read=1.0; /* This is a const table */ + join->positions[idx].records_out=1.0; /* This is a const table */ + join->positions[idx].records_init=1.0; /* This is a const table */ join->positions[idx].cond_selectivity= 1.0; join->positions[idx].ref_depend_map= 0; @@ -7688,24 +7765,30 @@ void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key) /* Estimate how many records we will get if we read just this table and apply - a part of WHERE that can be checked for it. + a part of WHERE that can be checked using only the current table and + const tables. - @detail + @param s Current JOIN_TAB + @param use_cond_selectivity Value of optimizer_use_condition_selectivity. + If > 1 then use table->cond_selecitivity. + @return 0.0 No matching rows + @return >= 1.0 Number of expected matching rows + + @details Estimate how many records we will get if we - read the given table with its "independent" access method (either quick select or full table/index scan), - - apply the part of WHERE that refers only to this table. + - apply the part of WHERE that refers only to this table and const tables. + - The result cannot be bigger than table records - @seealso - table_cond_selectivity() produces selectivity of condition that is checked - after joining rows from this table to rows from preceding tables. + @see also + table_after_join_selectivity() produces selectivity of condition that is + checked after joining rows from this table to rows from preceding tables. */ -inline -double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint, - uint use_cond_selectivity) +static double apply_selectivity_for_table(JOIN_TAB *s, + uint use_cond_selectivity) { - ha_rows records; double dbl_records; if (use_cond_selectivity > 1) @@ -7713,88 +7796,246 @@ double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint, TABLE *table= s->table; double sel= table->cond_selectivity; double table_records= rows2double(s->records); + DBUG_ASSERT(sel >= 0 && sel <= 1.0); + /* + table->cond_selectivity will include data from opt_range. + Here we check that this is indeeded the case. + Note that if table_records == 0, then 'sel' is probably 1 + */ + DBUG_ASSERT(table_records == 0 || + sel <= s->table->opt_range_condition_rows / + table_records); dbl_records= table_records * sel; - return dbl_records; + } + else + { + /* + This is only taking into considering constant key parts used with + this table! + If no such conditions existed the following should hold: + s->table->opt_range_condition_rows == s->found_rows == + s->records. + */ + DBUG_ASSERT(s->table->opt_range_condition_rows <= s->found_records); + dbl_records= rows2double(s->table->opt_range_condition_rows); } - records = s->found_records; - + DBUG_ASSERT(dbl_records <= s->records); /* - If there is a filtering condition on the table (i.e. ref analyzer found - at least one "table.keyXpartY= exprZ", where exprZ refers only to tables - preceding this table in the join order we're now considering), then - assume that 25% of the rows will be filtered out by this condition. - - This heuristic is supposed to force tables used in exprZ to be before - this table in join order. + Ensure we return at least one row if there is any possibility to have + a matching row. Having rows >= 1.0 helps ensure that when we calculate + total rows of joins, the number of resulting rows will not be less + after the join. In other words, we assume there is at least one matching + row when joining a row with the next table. + 0.0 is returned only if it is guaranteed there are no matching rows + (for example if the table is empty). */ - if (with_found_constraint) - records-= records/4; + return dbl_records ? MY_MAX(dbl_records, MIN_ROWS_AFTER_FILTERING) : 0.0; +} - /* - If applicable, get a more accurate estimate. Don't use the two - heuristics at once. - */ - if (s->table->opt_range_condition_rows != s->found_records) - records= s->table->opt_range_condition_rows; - dbl_records= (double)records; - return dbl_records; +/* + Take into account that the table's WHERE clause has conditions on earlier + tables that can reduce the number of accepted rows. + + @param records Number of original rows (after selectivity) + + If there is a filtering condition on the table (i.e. ref analyzer found + at least one "table.keyXpartY= exprZ", where exprZ refers only to tables + preceding this table in the join order we're now considering), then + assume that 25% of the rows will be filtered out by this condition. + + This heuristic is supposed to force tables used in exprZ to be before + this table in join order. +*/ + +static double use_found_constraint(double records) +{ + records-= records/4; + return records ? MY_MAX(records, MIN_ROWS_AFTER_FILTERING) : 0.0; } /* Calculate the cost of reading a set of rows trough an index + @param eq_ref True if there is only one matching key (EQ_REF) + Logically this is identical to the code in multi_range_read_info_const() excepts the function also takes into account io_blocks and multiple ranges. One main difference between the functions is that multi_range_read_info_const() adds a very small cost per range - (IDX_LOOKUP_COST) and also MULTI_RANGE_READ_SETUP_COST, to ensure that - 'ref' is preferred slightly over ranges. + MULTI_RANGE_READ_SETUP_COST, to ensure that 'ref' is preferred + over ranges. + + Note that this function assumes that index_only_cost is only to be + used with filtering (as cost.read_cost takes into account both + clustering and covered keys). index_only_cost does not include + KEY_COPY_COST as for filtering there is no copying of not accepted + keys. + + If eq_ref is not set, it means that we have to do one extra 'read_next' + on the index to verify that there is not more keys with the same value. + + WHERE_COST cost is not added to any result. */ -double cost_for_index_read(const THD *thd, const TABLE *table, uint key, - ha_rows records, ha_rows worst_seeks) +static ALL_READ_COST cost_for_index_read(const THD *thd, const TABLE *table, + uint key, ha_rows records, + bool eq_ref) { - DBUG_ENTER("cost_for_index_read"); - double cost; + ALL_READ_COST cost; handler *file= table->file; + ha_rows max_seeks; + ha_rows extra_reads= eq_ref ? 0 : 1; + DBUG_ENTER("cost_for_index_read"); + + max_seeks= (ha_rows) thd->variables.max_seeks_for_key; + set_if_bigger(records, 1); - set_if_smaller(records, (ha_rows) thd->variables.max_seeks_for_key); if (file->is_clustering_key(key)) - cost= file->read_time(key, 1, records); + { + cost.index_cost= + file->ha_keyread_clustered_time(key, 1, records+extra_reads, 0); + cost.copy_cost= rows2double(records) * file->ROW_COPY_COST; + /* There is no 'index_only_read' with a clustered index */ + cost.row_cost= {0,0}; + /* Caping of index_blocks will happen in handler::cost() */ + cost.max_index_blocks= MY_MIN(file->row_blocks(), max_seeks); + cost.max_row_blocks= 0; + } + else if (table->covering_keys.is_set(key) && !table->no_keyread) + { + cost.index_cost= file->ha_keyread_time(key, 1, records + extra_reads, 0); + cost.row_cost= {0,0}; + cost.copy_cost= rows2double(records) * file->KEY_COPY_COST; + cost.max_index_blocks= MY_MIN(file->index_blocks(key), max_seeks); + cost.max_row_blocks= 0; + } else - if (table->covering_keys.is_set(key)) - cost= file->keyread_time(key, 1, records); - else - cost= ((file->keyread_time(key, 0, records) + - file->read_time(key, 1, MY_MIN(records, worst_seeks)))); - - DBUG_PRINT("statistics", ("cost: %.3f", cost)); + { + cost.index_cost= file->ha_keyread_time(key, 1, records + extra_reads, 0); + /* ha_rnd_pos_time() includes time for copying the row */ + cost.row_cost= file->ha_rnd_pos_time(records); + cost.max_index_blocks= MY_MIN(file->index_blocks(key), max_seeks); + cost.max_row_blocks= MY_MIN(file->row_blocks(), max_seeks); + cost.copy_cost= 0; + } + DBUG_PRINT("statistics", ("index_cost: %.3f row_cost: %.3f", + file->cost(cost.index_cost), + file->cost(cost.row_cost))); DBUG_RETURN(cost); } -/* - Adjust cost from table->quick_costs calculated by - multi_range_read_info_const() to be comparable with cost_for_index_read() +/** + Apply filter if the filter is better than the current cost - This functions is needed because best_access_path() doesn't add - TIME_FOR_COMPARE to it's costs until very late. - Preferably we should fix so that all costs are comparably. - (All compared costs should include TIME_FOR_COMPARE for all found - rows). + @param thd Thread handler + @param table Table + @param cost Pointer to cost for current cost, which does not + include WHERE_COST cost. Will be updated to + new cost if filter is chosen. + Will be updated to new cost if filter is used. + @param records_arg Pointer to number of records for the current key. + Will be updated to records after filter, if filter is + used. + @param startup_cost Startup cost. Will be updated if filter is used. + @param fetch_cost Cost of finding the row, without where compare cost + @param index_only_cost Cost if fetching '*records_arg' key values + @param prev_records Number of record combinations in previous tables + + @return 'this' Filter is used (and variables are updated) + @return 0 Filter is worse than old plan */ -double adjust_quick_cost(double quick_cost, ha_rows records) +Range_rowid_filter_cost_info* Range_rowid_filter_cost_info:: +apply_filter(THD *thd, TABLE *table, ALL_READ_COST *cost, + double *records_arg, + double *startup_cost, + uint ranges, double prev_records) { - double cost= (quick_cost - MULTI_RANGE_READ_SETUP_COST - - rows2double(records)/TIME_FOR_COMPARE); - DBUG_ASSERT(cost > 0.0); - return cost; + handler *file= table->file; + bool use_filter; + double new_cost, org_cost, records= *records_arg, new_records; + double filter_startup_cost= get_setup_cost(); + double filter_lookup_cost= records * lookup_cost(); + double tmp; + ALL_READ_COST adjusted_cost; + + /* + Calculate number of resulting rows after filtering + Here we trust selectivity and do not adjust rows up even if + the end result is low. This means that new_records is allowed to be + be < 1.0 + */ + new_records= records * selectivity; + + /* + Calculate the cost of the filter based on that we had originally + 'records' rows and after the filter only 'new_records' accepted + rows. + Note that the rejected rows, we have only done a key read. We only + fetch the row and compare the where if the filter accepts the + row id. + In case of index only read, fetch_cost == index_only_cost. Even in this + the filter can give a better plan as we have to do less comparisons + with the WHERE clause. + + The io_cost is used to take into account that we have to do 1 key + lookup to find the first matching key in each range. + */ + + adjusted_cost= *cost; + /* We are going to read 'selectivity' fewer rows */ + adjusted_cost.row_cost.io*= selectivity; + adjusted_cost.row_cost.cpu*= selectivity; + adjusted_cost.copy_cost*= selectivity; + adjusted_cost.index_cost.cpu+= filter_lookup_cost; + + tmp= prev_records * WHERE_COST_THD(thd); + org_cost= (file->cost_for_reading_multiple_times(prev_records, + cost) + + records * tmp); + + new_cost= (file->cost_for_reading_multiple_times(prev_records, + &adjusted_cost) + + new_records * tmp + filter_startup_cost); + + DBUG_ASSERT(new_cost >= 0 && new_records >= 0); + use_filter= new_cost < org_cost; + + if (unlikely(thd->trace_started())) + { + Json_writer_object trace_filter(thd, "filter"); + trace_filter.add("rowid_filter_index", + table->key_info[get_key_no()].name). + add("index_only_cost", file->cost(cost->index_cost)). + add("filter_startup_cost", filter_startup_cost). + add("find_key_and_filter_lookup_cost", filter_lookup_cost). + add("filter_selectivity", selectivity). + add("original_rows", records). + add("new_rows", new_records). + add("original_access_cost", file->cost(cost)). + add("with_filter_access_cost", file->cost(&adjusted_cost)). + add("original_found_rows_cost", file->cost(cost->row_cost)). + add("with_filter_found_rows_cost", file->cost(adjusted_cost.row_cost)). + add("org_cost", org_cost). + add("filter_cost", new_cost). + add("filter_used", use_filter); + } + if (use_filter) + { + cost->row_cost= adjusted_cost.row_cost; + cost->index_cost= adjusted_cost.index_cost; + cost->copy_cost= adjusted_cost.copy_cost; + *records_arg= new_records; + (*startup_cost)+= filter_startup_cost; + return this; + } + return 0; } @@ -7804,7 +8045,7 @@ double adjust_quick_cost(double quick_cost, ha_rows records) The function finds the best access path to table 's' from the passed partial plan where an access path is the general term for any means to - access the data in 's'. An access path may use either an index or a scan, + cacess the data in 's'. An access path may use either an index or a scan, whichever is cheaper. The input partial plan is passed via the array 'join->positions' of length 'idx'. The chosen access method for 's' and its cost are stored in 'join->positions[idx]'. @@ -7826,6 +8067,25 @@ double adjust_quick_cost(double quick_cost, ha_rows records) None */ +struct best_plan +{ + double cost; // Smallest cost found + double records; // Old 'Records' + double records_read; // Records accessed + double records_after_filter; // Records_read + filter + double records_out; // Smallest record count seen + Range_rowid_filter_cost_info *filter; // Best filter + KEYUSE *key; // Best key + SplM_plan_info *spl_plan; + table_map ref_depends_map; + enum join_type type; + uint forced_index; + uint max_key_part; + table_map found_ref; + bool uses_jbuf; +}; + + void best_access_path(JOIN *join, JOIN_TAB *s, @@ -7838,15 +8098,11 @@ best_access_path(JOIN *join, POSITION *loose_scan_pos) { THD *thd= join->thd; - uint use_cond_selectivity= thd->variables.optimizer_use_condition_selectivity; - KEYUSE *best_key= 0; - uint best_max_key_part= 0; + uint use_cond_selectivity= + thd->variables.optimizer_use_condition_selectivity; + TABLE *table= s->table; + handler *file= table->file; my_bool found_constraint= 0; - double best= DBL_MAX; - double best_time= DBL_MAX; - double records= DBL_MAX; - ha_rows records_for_key= 0; - table_map best_ref_depends_map= 0; /* key_dependent is 0 if all key parts could be used or if there was an EQ_REF table found (which uses all key parts). In other words, we cannot @@ -7854,24 +8110,42 @@ best_access_path(JOIN *join, Otherwise it's a bitmap of tables that could improve key usage. */ table_map key_dependent= 0; - Range_rowid_filter_cost_info *best_filter= 0; - double tmp; - double keyread_tmp= 0; + ALL_READ_COST tmp; ha_rows rec; - bool best_uses_jbuf= FALSE; MY_BITMAP *eq_join_set= &s->table->eq_join_set; KEYUSE *hj_start_key= 0; - SplM_plan_info *spl_plan= 0; - Range_rowid_filter_cost_info *filter= 0; - const char* cause= NULL; - enum join_type best_type= JT_UNKNOWN, type= JT_UNKNOWN; - - disable_jbuf= disable_jbuf || idx == join->const_tables; - Loose_scan_opt loose_scan_opt; + struct best_plan best; + Json_writer_object trace_wrapper(thd, "best_access_path"); DBUG_ENTER("best_access_path"); - Json_writer_object trace_wrapper(thd, "best_access_path"); + /* + Assume that there is at least one accepted row from previous table + combinations. + This fixes a problem when the selectivity for the preceding table + combinations becomes so high that record_count becomes << 1.0, + which makes the cost for the current table so low that it does not + matter when calculating the best plans. + */ + set_if_bigger(record_count, 1.0); + + best.cost= DBL_MAX; + best.records= DBL_MAX; + best.records_read= DBL_MAX; + best.records_after_filter= DBL_MAX; + best.records_out= table->stat_records() * table->cond_selectivity; + best.filter= 0; + best.key= 0; + best.max_key_part= 0; + best.type= JT_UNKNOWN; + best.forced_index= MAX_KEY; + best.found_ref= 0; + best.ref_depends_map= 0; + best.uses_jbuf= FALSE; + best.spl_plan= 0; + + pos->loops= record_count; + disable_jbuf= disable_jbuf || idx == join->const_tables; trace_wrapper.add_table_name(s); @@ -7879,36 +8153,45 @@ best_access_path(JOIN *join, loose_scan_opt.init(join, s, remaining_tables); - if (s->table->is_splittable()) - spl_plan= s->choose_best_splitting(record_count, remaining_tables); + if (table->is_splittable()) + best.spl_plan= s->choose_best_splitting(record_count, remaining_tables); + + if (unlikely(thd->trace_started())) + { + Json_writer_object info(thd, "plan_details"); + info.add("record_count", record_count); + } Json_writer_array trace_paths(thd, "considered_access_paths"); if (s->keyuse) { /* Use key if possible */ - KEYUSE *keyuse; - KEYUSE *start_key=0; - TABLE *table= s->table; - double best_records= DBL_MAX; + KEYUSE *keyuse, *start_key= 0; uint max_key_part=0; + enum join_type type= JT_UNKNOWN; + double cur_cost; /* Test how we can use keys */ rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key for (keyuse=s->keyuse ; keyuse->table == table ;) { KEY *keyinfo; + const char *cause= NULL; ulong key_flags; uint key_parts; key_part_map found_part= 0; - key_part_map notnull_part=0; // key parts which won't have NULL in lookup tuple. + /* key parts which won't have NULL in lookup tuple */ + key_part_map notnull_part=0; table_map found_ref= 0; uint key= keyuse->key; - filter= 0; bool ft_key= (keyuse->keypart == FT_KEYPART); /* Bitmap of keyparts where the ref access is over 'keypart=const': */ key_part_map const_part= 0; /* The or-null keypart in ref-or-null access: */ key_part_map ref_or_null_part= 0; key_part_map all_parts= 0; + double startup_cost= s->startup_cost; + double records_after_filter, records_best_filter, records; + Range_rowid_filter_cost_info *filter= 0; if (is_hash_join_key_no(key)) { @@ -7947,7 +8230,7 @@ best_access_path(JOIN *join, do /* For each way to access the keypart */ { /* - if 1. expression doesn't refer to forward tables + If 1. expression does not refer to forward tables 2. we won't get two ref-or-null's */ all_parts|= keyuse->keypart_map; @@ -7970,7 +8253,8 @@ best_access_path(JOIN *join, (found_ref | keyuse->used_tables)); if (tmp2 < best_prev_record_reads) { - best_part_found_ref= keyuse->used_tables & ~join->const_table_map; + best_part_found_ref= (keyuse->used_tables & + ~join->const_table_map); best_prev_record_reads= tmp2; } if (rec > keyuse->ref_table_rows) @@ -7981,6 +8265,16 @@ best_access_path(JOIN *join, */ if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) ref_or_null_part |= keyuse->keypart_map; + + /* + Remember if there is a WHERE condition that contains + 'key_part=expression_with_only_accessible_tables' + We ignore const tables as these are handled by selectivity + code (const table fields are treated as constants). + */ + found_constraint|= (keyuse->used_tables & + ~(remaining_tables | + join->const_table_map)); } else if (!(found_part & keyuse->keypart_map)) key_parts_dependent|= keyuse->used_tables; @@ -7993,6 +8287,7 @@ best_access_path(JOIN *join, if (all_parts & 1) key_dependent|= key_parts_dependent; found_ref|= best_part_found_ref; + /* Remember if the key expression used previous non const tables */ } while (keyuse->table == table && keyuse->key == key); /* @@ -8011,18 +8306,36 @@ best_access_path(JOIN *join, if (ft_key) { /* - Really, there should be records=0.0 (yes!) - but 1.0 would be probably safer + Fulltext indexes are preformed the following way: + - In the prepare step it performs the search, collects all positions + in an array, sorts it. + - If optimizer decides to use the ft index access method it simply' + returns positions from the array one by one + - If optimizer decides to use something else (another index, table + scan), then it'll use binary search in the array to find the + position. + + The following code puts the cost down to very small as the prep + step will always be done and the cost to fetch the row from memory + is very small. + Alternatively we could use the cost of an EQ_REF here. + */ + tmp.reset(); + tmp.row_cost.cpu= file->ROW_COPY_COST; + /* + We don't know how many records will match. However, we want to have + the fulltext search done early, so we put the number of records + to be very low. */ - tmp= prev_record_reads(join_positions, idx, found_ref); records= 1.0; type= JT_FT; - trace_access_idx.add("access_type", join_type_str[type]) - .add("full-text index", keyinfo->name); + if (unlikely(trace_access_idx.trace_started())) + trace_access_idx. + add("access_type", join_type_str[type]). + add("full-text index", keyinfo->name); } else { - found_constraint= MY_TEST(found_part); loose_scan_opt.check_ref_access_part1(s, key, start_key, found_part); /* Check if we found full key */ @@ -8036,28 +8349,45 @@ best_access_path(JOIN *join, - equalities we are using reject NULLs (3) then the estimate is rows=1. */ - if ((key_flags & (HA_NOSAME | HA_EXT_NOSAME)) && // (1) + if ((key_flags & (HA_NOSAME | HA_EXT_NOSAME)) && // (1) (!(key_flags & HA_NULL_PART_KEY) || // (2) all_key_parts == notnull_part)) // (3) { + double adjusted_cost; /* Check that eq_ref_tables are correctly updated */ DBUG_ASSERT(join->eq_ref_tables & table->map); - /* TODO: Adjust cost for covering and clustering key */ type= JT_EQ_REF; - trace_access_idx.add("access_type", join_type_str[type]) - .add("index", keyinfo->name); + if (unlikely(trace_access_idx.trace_started())) + trace_access_idx. + add("access_type", join_type_str[type]). + add("index", keyinfo->name); if (!found_ref && table->opt_range_keys.is_set(key)) - tmp= adjust_quick_cost(table->opt_range[key].cost, 1); + { + /* Ensure that the cost is identical to the range cost */ + table->opt_range[key].get_costs(&tmp); + } else - tmp= table->file->avg_io_cost(); - tmp*= prev_record_reads(join_positions, idx, found_ref); - records=1.0; + { + tmp= cost_for_index_read(thd, table, key, 1, 1); + } + /* + Calculate an adjusted cost based on how many records are read + This will be multipled by record_count. + */ + adjusted_cost= (prev_record_reads(join_positions, idx, found_ref) / + record_count); + set_if_smaller(adjusted_cost, 1.0); + tmp.row_cost.cpu*= adjusted_cost; + tmp.index_cost.cpu*= adjusted_cost; + records= 1.0; } else { type= JT_REF; - trace_access_idx.add("access_type", join_type_str[type]) - .add("index", keyinfo->name); + if (unlikely(trace_access_idx.trace_started())) + trace_access_idx. + add("access_type", join_type_str[type]). + add("index", keyinfo->name); if (!found_ref) { /* We found a const key */ /* @@ -8079,19 +8409,19 @@ best_access_path(JOIN *join, */ if (table->opt_range_keys.is_set(key)) { + /* Ensure that the cost is identical to the range cost */ records= (double) table->opt_range[key].rows; trace_access_idx.add("used_range_estimates", true); - tmp= adjust_quick_cost(table->opt_range[key].cost, - table->opt_range[key].rows); - goto got_cost; - } - else - { - /* quick_range couldn't use key! */ - records= (double) s->records/rec; - trace_access_idx.add("used_range_estimates", false) - .add("reason", "not available"); + + table->opt_range[key].get_costs(&tmp); + goto got_cost2; } + /* quick_range couldn't use key! */ + records= (double) s->records/rec; + if (unlikely(trace_access_idx.trace_started())) + trace_access_idx. + add("used_range_estimates", false). + add("reason", "not available"); } else { @@ -8103,9 +8433,11 @@ best_access_path(JOIN *join, (1.0 + ((double) (table->s->max_key_length-keyinfo->key_length) / (double) table->s->max_key_length))); - if (records < 2.0) - records=2.0; /* Can't be as good as a unique */ + set_if_smaller(records, (double)s->records); + if (records < 1.0) + records= 1.0; /* Can't be as good as a unique */ } + /* ReuseRangeEstimateForRef-2: We get here if we could not reuse E(#rows) from range optimizer. Make another try: @@ -8126,44 +8458,46 @@ best_access_path(JOIN *join, records= (double) table->opt_range[key].rows; trace_access_idx.add("used_range_estimates", "clipped down"); } - else + else if (unlikely(trace_access_idx.trace_started())) { - trace_access_idx.add("used_range_estimates", false); if (table->opt_range_keys.is_set(key)) { - trace_access_idx.add("reason", "not better than ref estimates"); + trace_access_idx. + add("used_range_estimates",false). + add("reason", "not better than ref estimates"); } else { - trace_access_idx.add("reason", "not available"); + trace_access_idx. + add("used_range_estimates", false). + add("reason", "not available"); } } } - /* Limit the number of matched rows */ - tmp= cost_for_index_read(thd, table, key, (ha_rows) records, - (ha_rows) s->worst_seeks); - records_for_key= (ha_rows) records; - set_if_smaller(records_for_key, thd->variables.max_seeks_for_key); - keyread_tmp= table->file->keyread_time(key, 1, records_for_key); - got_cost: - tmp= COST_MULT(tmp, record_count); - keyread_tmp= COST_MULT(keyread_tmp, record_count); + /* Calculate the cost of the index access */ + tmp= cost_for_index_read(thd, table, key, + (ha_rows) records, 0); } } else { type = ref_or_null_part ? JT_REF_OR_NULL : JT_REF; - trace_access_idx.add("access_type", join_type_str[type]) - .add("index", keyinfo->name); + if (unlikely(trace_access_idx.trace_started())) + trace_access_idx. + add("access_type", join_type_str[type]). + add("index", keyinfo->name); /* Use as much key-parts as possible and a uniq key is better than a not unique key - Set tmp to (previous record count) * (records / combination) + Set tmp to the cost of the accessing the expected number of + records. */ if ((found_part & 1) && - (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) || + (!(table->key_info[key].index_flags & HA_ONLY_WHOLE_INDEX) || found_part == PREV_BITS(uint,keyinfo->user_defined_key_parts))) { + double extra_cost= 0; + max_key_part= max_part_bit(found_part); /* ReuseRangeEstimateForRef-3: @@ -8189,7 +8523,7 @@ best_access_path(JOIN *join, We also have a property that "range optimizer produces equal or tighter set of scan intervals than ref(const) optimizer". Each of the intervals in (**) are "tightest possible" intervals when - one limits itself to using keyparts 1..K (which we do in #2). + one limits itself to using keyparts 1..K (which we do in #2). From here it follows that range access used either one, or both of the (I1) and (I2) intervals: @@ -8209,8 +8543,11 @@ best_access_path(JOIN *join, table->opt_range[key].ranges == 1 + MY_TEST(ref_or_null_part)) //(C3) { records= (double) table->opt_range[key].rows; - tmp= adjust_quick_cost(table->opt_range[key].cost, - table->opt_range[key].rows); + table->opt_range[key].get_costs(&tmp); + /* + TODO: Disable opt_range testing below for this range as we can + always use this ref instead. + */ trace_access_idx.add("used_range_estimates", true); goto got_cost2; } @@ -8243,7 +8580,8 @@ best_access_path(JOIN *join, if (!found_ref && // (1) records < rows) // (3) { - trace_access_idx.add("used_range_estimates", "clipped up"); + trace_access_idx.add("used_range_estimates", + "clipped up"); records= rows; } } @@ -8283,8 +8621,8 @@ best_access_path(JOIN *join, a*keyinfo->user_defined_key_parts - rec_per_key)/ (keyinfo->user_defined_key_parts-1); else - records= a; - set_if_bigger(records, 1.0); + records= rows2double(s->records); + set_if_bigger(records, MIN_ROWS_AFTER_FILTERING); } } @@ -8292,6 +8630,7 @@ best_access_path(JOIN *join, { /* We need to do two key searches to find row */ records *= 2.0; + extra_cost= s->table->file->KEY_LOOKUP_COST; } /* @@ -8320,36 +8659,39 @@ best_access_path(JOIN *join, } } - /* Limit the number of matched rows */ - tmp= cost_for_index_read(thd, table, key, (ha_rows) records, - (ha_rows) s->worst_seeks); - records_for_key= (ha_rows) records; - set_if_smaller(records_for_key, thd->variables.max_seeks_for_key); - keyread_tmp= table->file->keyread_time(key, 1, records_for_key); - got_cost2: - tmp= COST_MULT(tmp, record_count); - keyread_tmp= COST_MULT(keyread_tmp, record_count); + set_if_smaller(records, (double) s->records); + tmp= cost_for_index_read(thd, table, key, (ha_rows)records, 0); + tmp.copy_cost+= extra_cost; } else { if (!(found_part & 1)) cause= "no predicate for first keypart"; - tmp= best_time; // Do nothing + else + cause= "No full key found"; + trace_access_idx.add("chosen", false).add("cause", cause); + continue; } } - tmp= COST_ADD(tmp, s->startup_cost); - loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp, + got_cost2: + loose_scan_opt.check_ref_access_part2(key, start_key, records, + file->cost(&tmp) + startup_cost, found_ref); } /* not ft_key */ - if (records < DBL_MAX && - (found_part & 1) && // start_key->key can be used for index access - (table->file->index_flags(start_key->key,0,1) & - HA_DO_RANGE_FILTER_PUSHDOWN)) + if (records == DBL_MAX) // Key not usable + continue; + + records_best_filter= records_after_filter= records; + + /* + Check if we can use a filter. + Records can be 0 in case of empty tables. + */ + if ((found_part & 1) && records && + table->can_use_rowid_filter(start_key->key)) { - double rows= record_count * records; - /* If we use filter F with selectivity s the the cost of fetching data by key using this filter will be @@ -8370,7 +8712,6 @@ best_access_path(JOIN *join, Here we have: cost_of_fetching_1_row = tmp/rows cost_of_fetching_1_key_tuple = keyread_tmp/rows - access_cost_factor is the gain we expect for using rowid filter. An access_cost_factor of 1.0 means that keyread_tmp is 0 (using key read is infinitely fast) and the gain for each row when @@ -8395,50 +8736,71 @@ best_access_path(JOIN *join, We cannot use filter with JT_EQ_REF as in this case 'tmp' is number of rows from prev_record_read() and keyread_tmp is 0. These numbers are not usable with rowid filter code. - */ - double access_cost_factor= MY_MIN((rows - keyread_tmp) / rows, 1.0); - if (!(records < s->worst_seeks && - records <= thd->variables.max_seeks_for_key)) - trace_access_idx.add("rowid_filter_skipped", "worst/max seeks clipping"); - else if (access_cost_factor <= 0.0) - trace_access_idx.add("rowid_filter_skipped", "cost_factor <= 0"); - else if (type != JT_EQ_REF) - { - filter= - table->best_range_rowid_filter_for_partial_join(start_key->key, - rows, - access_cost_factor); - if (filter) - { - tmp-= filter->get_adjusted_gain(rows) - filter->get_cmp_gain(rows); - DBUG_ASSERT(tmp >= 0); - trace_access_idx.add("rowid_filter_key", - table->key_info[filter->key_no].name); - } - } + */ + filter= table->best_range_rowid_filter(start_key->key, + records, + file->cost(&tmp), + file->cost(tmp.index_cost), + record_count, + &records_best_filter); + set_if_smaller(best.records_out, records_best_filter); + if (filter) + filter= filter->apply_filter(thd, table, &tmp, + &records_after_filter, + &startup_cost, + 1, record_count); } - trace_access_idx.add("rows", records).add("cost", tmp); - if (tmp + 0.0001 < best_time - records/TIME_FOR_COMPARE) + tmp.copy_cost+= records_after_filter * WHERE_COST_THD(thd); + cur_cost= file->cost_for_reading_multiple_times(record_count, &tmp); + cur_cost= COST_ADD(cur_cost, startup_cost); + + if (unlikely(trace_access_idx.trace_started())) + { + trace_access_idx. + add("rows", records_after_filter). + add("cost", cur_cost); + } + + /* + The COST_EPS is here to ensure we use the first key if there are + two 'identical keys' that could be used. + */ + if (cur_cost + COST_EPS < best.cost) { trace_access_idx.add("chosen", true); - best_time= COST_ADD(tmp, records/TIME_FOR_COMPARE); - best= tmp; - best_records= records; - best_key= start_key; - best_max_key_part= max_key_part; - best_ref_depends_map= found_ref; - best_filter= filter; - best_type= type; + best.cost= cur_cost; + /* + We use 'records' instead of 'records_after_filter' here as we want + to have EXPLAIN print the number of rows found by the key access. + */ + best.records= records; // Records before filter! + best.records_read= records; + /* + If we are using 'use_cond_selectivity > 1' then + table_after_join_selectivity() may take into account other + filters that what is currently used so we have to use + records_after_filter. If 'use_cond_selectivity <= 1 then we + can use information from the best filter. + */ + best.records_after_filter= ((use_cond_selectivity > 1) ? + records_after_filter : + records_best_filter); + best.key= start_key; + best.found_ref= found_ref; + best.max_key_part= max_key_part; + best.ref_depends_map= found_ref; + best.filter= filter; + best.type= type; } - else + else if (unlikely(thd->trace_started())) { - trace_access_idx.add("chosen", false) - .add("cause", cause ? cause : "cost"); + trace_access_idx. + add("chosen", false). + add("cause", cause ? cause : "cost"); } - cause= nullptr; + set_if_smaller(best.records_out, records); } /* for each key */ - records= best_records; } else { @@ -8457,15 +8819,19 @@ best_access_path(JOIN *join, */ if (s->key_start_dependent) key_dependent= s->key_dependent; - /* Add dependencey for sub queries */ + + /* Add dependency for sub queries */ key_dependent|= s->embedded_dependent; - } + + } /* if (s->keyuse) */ + + /* Check that s->key_dependent contains all used_tables found in s->keyuse */ key_dependent&= ~PSEUDO_TABLE_BITS; DBUG_ASSERT((key_dependent & (s->key_dependent | s->embedded_dependent)) == key_dependent); - /* + /* If there is no key to access the table, but there is an equi-join predicate connecting the table with the privious tables then we consider the possibility of using hash join. @@ -8473,46 +8839,77 @@ best_access_path(JOIN *join, (1) s is inner table of semi-join -> join cache is allowed for semijoins (2) s is inner table of outer join -> join cache is allowed for outer joins */ - if (idx > join->const_tables && best_key == 0 && + if (idx > join->const_tables && best.key == 0 && (join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) && join->max_allowed_join_cache_level > 2 && !bitmap_is_clear_all(eq_join_set) && !disable_jbuf && (!s->emb_sj_nest || join->allowed_semijoin_with_cache) && // (1) - (!(s->table->map & join->outer_join) || + (!(table->map & join->outer_join) || join->allowed_outer_join_with_cache)) // (2) { - double join_sel= 0.1; - /* Estimate the cost of the hash join access to the table */ - double rnd_records= matching_candidates_in_table(s, found_constraint, - use_cond_selectivity); + double refills, row_copy_cost, cmp_time, cur_cost, records_table_filter; + /* Estimate the cost of the hash join access to the table */ + double rnd_records= apply_selectivity_for_table(s, use_cond_selectivity); + records_table_filter= ((found_constraint) ? + use_found_constraint(rnd_records) : + rnd_records); - tmp= s->quick ? s->quick->read_time : s->scan_time(); - double cmp_time= (s->records - rnd_records)/TIME_FOR_COMPARE; - tmp= COST_ADD(tmp, cmp_time); + DBUG_ASSERT(rnd_records <= rows2double(s->found_records) + 0.5); + set_if_smaller(best.records_out, records_table_filter); + + /* + The following cost calculation is identical to the cost calculation for + the join cache later on, except for the HASH_FANOUT + */ + if (s->quick) + { + /* + Cost of reading rows through opt_range including comparing the rows + with the attached WHERE clause. + */ + cur_cost= s->quick->read_time; + } + else + cur_cost= s->cached_scan_and_compare_time; /* We read the table as many times as join buffer becomes full. */ + refills= (1.0 + floor((double) cache_record_length(join,idx) * + record_count / + (double) thd->variables.join_buff_size)); + cur_cost= COST_MULT(cur_cost, refills); - double refills= (1.0 + floor((double) cache_record_length(join,idx) * - record_count / - (double) thd->variables.join_buff_size)); - tmp= COST_MULT(tmp, refills); - best_time= COST_ADD(tmp, - COST_MULT((record_count*join_sel) / TIME_FOR_COMPARE, - rnd_records)); - best= tmp; - records= rnd_records; - best_key= hj_start_key; - best_ref_depends_map= 0; - best_uses_jbuf= TRUE; - best_filter= 0; - best_type= JT_HASH; + /* + Cost of doing the hash lookup and check all matching rows with the + WHERE clause. + We assume here that, thanks to the hash, we don't have to compare all + row combinations, only a HASH_FANOUT (10%) rows in the cache. + */ + row_copy_cost= (ROW_COPY_COST_THD(thd) * 2 * + JOIN_CACHE_ROW_COPY_COST_FACTOR(thd)); + cmp_time= (record_count * row_copy_cost + + rnd_records * record_count * HASH_FANOUT * + ((idx - join->const_tables) * row_copy_cost + + WHERE_COST_THD(thd))); + cur_cost= COST_ADD(cur_cost, cmp_time); + + best.cost= cur_cost; + best.records_read= best.records_after_filter= rows2double(s->records); + best.records= rnd_records; + best.key= hj_start_key; + best.ref_depends_map= 0; + best.uses_jbuf= TRUE; + best.filter= 0; + best.type= JT_HASH; Json_writer_object trace_access_hash(thd); - trace_access_hash.add("type", "hash"); - trace_access_hash.add("index", "hj-key"); - trace_access_hash.add("rnd_records", rnd_records); - trace_access_hash.add("cost", best); - trace_access_hash.add("chosen", true); + if (unlikely(trace_access_hash.trace_started())) + trace_access_hash. + add("type", "hash"). + add("index", "hj-key"). + add("rows", rnd_records). + add("refills", refills). + add("cost", best.cost). + add("chosen", true); } /* @@ -8551,19 +8948,26 @@ best_access_path(JOIN *join, be used for cases with small datasets, which is annoying. */ Json_writer_object trace_access_scan(thd); - if ((records >= s->found_records || best > s->read_time) && // (1) - !(best_key && best_key->key == MAX_KEY) && // (2) + if ((best.records_read >= s->found_records || + best.cost > s->read_time) && // (1) + !(best.key && best.key->key == MAX_KEY) && // (2) !(s->quick && s->quick->get_type() != QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX && // (2) - best_key && s->quick->index == best_key->key && // (2) - best_max_key_part >= s->table->opt_range[best_key->key].key_parts) &&// (2) - !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3) - ! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3) - !(s->table->force_index && best_key && !s->quick) && // (4) - !(best_key && s->table->pos_in_table_list->jtbm_subselect)) // (5) + best.key && s->quick->index == best.key->key && // (2) + best.max_key_part >= table->opt_range[best.key->key].key_parts) &&// (2) + !((file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3) + !table->covering_keys.is_clear_all() && best.key && !s->quick) &&// (3) + !(table->force_index_join && best.key && !s->quick) && // (4) + !(best.key && table->pos_in_table_list->jtbm_subselect)) // (5) { // Check full join - double rnd_records= matching_candidates_in_table(s, found_constraint, - use_cond_selectivity); + double records_after_filter, org_records; + double records_best_filter, cur_cost; + Range_rowid_filter_cost_info *filter= 0; + double startup_cost= s->startup_cost; + const char *scan_type= ""; + enum join_type type; + uint forced_index= MAX_KEY; + bool force_plan= 0; /* Range optimizer never proposes a RANGE if it isn't better @@ -8571,171 +8975,325 @@ best_access_path(JOIN *join, Here we estimate its cost. */ - filter= 0; if (s->quick) { /* For each record we: - read record range through 'quick' - skip rows which does not satisfy WHERE constraints - TODO: + + Note that s->quick->read_time includes the cost of comparing + the row with the where clause (WHERE_COST) + + TODO: We take into account possible use of join cache for ALL/index access (see first else-branch below), but we don't take it into account here for range/index_merge access. Find out why this is so. */ - double cmp_time= (s->found_records - rnd_records) / TIME_FOR_COMPARE; - tmp= COST_MULT(record_count, - COST_ADD(s->quick->read_time, cmp_time)); + cur_cost= COST_MULT(s->quick->read_time, record_count); - if ( s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE) + /* + Use record count from range optimizer. + This is done to make records found comparable to what we get with + 'ref' access. + */ + org_records= records_after_filter= rows2double(s->found_records); + records_best_filter= org_records; + set_if_smaller(best.records_out, records_best_filter); + + if (s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE) { - double rows= record_count * s->found_records; - double access_cost_factor= MY_MIN(tmp / rows, 1.0); uint key_no= s->quick->index; + TABLE::OPT_RANGE *range= &table->opt_range[key_no]; - /* See the comment concerning using rowid filter for with ref access */ - keyread_tmp= s->table->opt_range[key_no].index_only_cost * - record_count; - access_cost_factor= MY_MIN((rows - keyread_tmp) / rows, 1.0); - if (access_cost_factor > 0.0) + /* + Ensure that 'range' and 's' are comming from the same source + The complex 'double' comparison is there because floating point + registers complications when costs are calculated. + */ + DBUG_ASSERT(range->rows == s->found_records); + DBUG_ASSERT((range->cost.total_cost() == 0.0 && + s->quick->read_time == 0.0) || + (range->cost.total_cost() / s->quick->read_time <= 1.0000001 && + range->cost.total_cost() / s->quick->read_time >= 0.9999999)); + + range->get_costs(&tmp); + if (table->can_use_rowid_filter(key_no)) { - filter= - s->table-> - best_range_rowid_filter_for_partial_join(key_no, rows, - access_cost_factor); + filter= table->best_range_rowid_filter(key_no, + rows2double(range->rows), + file->cost(&tmp), + file->cost(tmp.index_cost), + record_count, + &records_best_filter); + set_if_smaller(best.records_out, records_best_filter); if (filter) { - tmp-= filter->get_adjusted_gain(rows); - DBUG_ASSERT(tmp >= 0); + filter= filter->apply_filter(thd, table, &tmp, + &records_after_filter, + &startup_cost, + range->ranges, + record_count); + if (filter) + { + tmp.row_cost.cpu+= records_after_filter * WHERE_COST_THD(thd); + cur_cost= file->cost_for_reading_multiple_times(record_count, + &tmp); + cur_cost= COST_ADD(cur_cost, startup_cost); + startup_cost= 0; // Avoid adding it again later + table->opt_range[key_no].selectivity= filter->selectivity; + } } } - else - trace_access_scan.add("rowid_filter_skipped", "cost_factor <= 0"); - + if (best.key && key_no == best.key->key && + !best.found_ref && + best.max_key_part < table->opt_range[best.key->key].key_parts && + table->opt_range[best.key->key].ranges == 1) + { + /* + Force to use range as it is using the 'best key' and using more + key parts (and thus will read less rows) + */ + force_plan= 1; + } type= JT_RANGE; } else { type= JT_INDEX_MERGE; - best_filter= 0; } loose_scan_opt.check_range_access(join, idx, s->quick); } else { - /* Estimate cost of reading table. */ - if (s->table->force_index && !best_key) // index scan - { - type= JT_NEXT; - tmp= s->table->file->read_time(s->ref.key, 1, s->records); - } - else // table scan - { - tmp= s->scan_time(); - type= JT_ALL; - } + double records_table_filter; - if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache + /* We will now calculate cost of scan, with or without join buffer */ + records_best_filter= records_after_filter= + apply_selectivity_for_table(s, use_cond_selectivity); + records_table_filter= ((found_constraint) ? + use_found_constraint(records_after_filter) : + records_after_filter); + + DBUG_ASSERT(records_after_filter <= s->records); + DBUG_ASSERT(records_after_filter <= s->found_records); + + set_if_smaller(best.records_out, records_table_filter); + + org_records= rows2double(s->records); + + /* Estimate cost of reading table. */ + if (s->cached_forced_index_type) { - /* - For each record we have to: - - read the whole table record - - skip rows which does not satisfy join condition - */ - double cmp_time= (s->records - rnd_records)/TIME_FOR_COMPARE; - tmp= COST_MULT(record_count, COST_ADD(tmp,cmp_time)); + type= s->cached_forced_index_type; + cur_cost= s->cached_forced_index_cost; + forced_index= s->cached_forced_index; } else { - double refills= (1.0 + floor((double) cache_record_length(join,idx) * - (record_count / - (double) thd->variables.join_buff_size))); - tmp= COST_MULT(tmp, refills); - /* - We don't make full cartesian product between rows in the scanned - table and existing records because we skip all rows from the - scanned table, which does not satisfy join condition when - we read the table (see flush_cached_records for details). Here we - take into account cost to read and skip these records. + if (table->force_index_join && !best.key) + { + /* + The query is using 'forced_index' and we did not find a usable key. + Calculate cost of a table scan with the forced index. + */ + type= JT_NEXT; + if (s->cached_covering_key != MAX_KEY) + { + /* Use value from estimate_scan_time */ + forced_index= s->cached_covering_key; + cur_cost= s->cached_scan_and_compare_time; + } + else + { +#ifdef FORCE_INDEX_SHOULD_FORCE_INDEX_SCAN + /* No cached key, use shortest allowed key */ + key_map keys= *file->keys_to_use_for_scanning(); + keys.intersect(table->keys_in_use_for_query); + if ((forced_index= find_shortest_key(table, &keys)) < MAX_KEY) + { + ALL_READ_COST cost= cost_for_index_read(thd, table, + forced_index, + s->records, 0); + cur_cost= file->cost(cost); + /* Calculate cost of checking the attached WHERE */ + cur_cost= COST_ADD(cur_cost, + s->records * WHERE_COST_THD(thd)); + } + else +#endif + { + /* No usable key, use table scan */ + cur_cost= s->cached_scan_and_compare_time; + type= JT_ALL; + } + } + } + else // table scan + { + cur_cost= s->cached_scan_and_compare_time; + type= JT_ALL; + } + /* Cache result for other calls */ + s->cached_forced_index_type= type; + s->cached_forced_index_cost= cur_cost; + s->cached_forced_index= forced_index; + } + + if ((table->map & join->outer_join) || disable_jbuf) + { + /* + Simple scan + We estimate we have to read org_records rows. + records_after_filter rows will survive the where check of constants. + 'best.records_out' rows will survive after the check against columns + from previous tables. */ - double cmp_time= (s->records - rnd_records)/TIME_FOR_COMPARE; - tmp= COST_ADD(tmp, cmp_time); + scan_type= "scan"; + + /* + We have to compare each row set against all previous row combinations + */ + cur_cost= COST_MULT(cur_cost, record_count); + } + else + { + /* Scan trough join cache */ + double cmp_time, row_copy_cost, refills; + + /* + Note that the cost of checking all rows against the table specific + WHERE is already included in cur_cost. + */ + scan_type= "scan_with_join_cache"; + + /* Calculate cost of refills */ + refills= (1.0 + floor((double) cache_record_length(join,idx) * + (record_count / + (double) thd->variables.join_buff_size))); + cur_cost= COST_MULT(cur_cost, refills); + + /* We come here only if there are already rows in the join cache */ + DBUG_ASSERT(idx != join->const_tables); + /* + records_after_filter is the number of rows that have survived + the table specific WHERE check that only involves constants. + + Calculate cost of: + - Copying all previous record combinations to the join cache + - Copying the tables from the join cache to table records + - Checking the WHERE against the final row combination + */ + row_copy_cost= (ROW_COPY_COST_THD(thd) * + JOIN_CACHE_ROW_COPY_COST_FACTOR(thd)); + cmp_time= (record_count * row_copy_cost + + records_after_filter * record_count * + ((idx - join->const_tables) * row_copy_cost + + WHERE_COST_THD(thd))); + cur_cost= COST_ADD(cur_cost, cmp_time); } } - trace_access_scan.add("access_type", type == JT_ALL ? - "scan" : - join_type_str[type]); /* Splitting technique cannot be used with join cache */ - if (s->table->is_splittable()) - tmp+= s->table->get_materialization_cost(); - else - tmp+= s->startup_cost; + if (table->is_splittable()) + startup_cost= table->get_materialization_cost(); + cur_cost+= startup_cost; - /* - We estimate the cost of evaluating WHERE clause for found records - as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus - tmp give us total cost of using TABLE SCAN - */ + if (unlikely(trace_access_scan.trace_started())) + { + trace_access_scan. + add("access_type", + type == JT_ALL ? scan_type : join_type_str[type]); + if (type == JT_RANGE) + trace_access_scan. + add("range_index", table->key_info[s->quick->index].name); + trace_access_scan. + add("rows", org_records). + add("rows_after_filter", records_after_filter). + add("rows_out", best.records_out). + add("cost", cur_cost); + if (type == JT_ALL) + { + trace_access_scan.add("index_only", + (s->cached_covering_key != MAX_KEY)); + } + } - const double best_filter_cmp_gain= best_filter - ? best_filter->get_cmp_gain(record_count * records) - : 0; - trace_access_scan.add("resulting_rows", rnd_records); - trace_access_scan.add("cost", tmp); - - if (best == DBL_MAX || - COST_ADD(tmp, record_count/TIME_FOR_COMPARE*rnd_records) < - (best_key->is_for_hash_join() ? best_time : - COST_ADD(best - best_filter_cmp_gain, - record_count/TIME_FOR_COMPARE*records))) + if (cur_cost + COST_EPS < best.cost || force_plan) { /* If the table has a range (s->quick is set) make_join_select() will ensure that this will be used */ - best= tmp; - records= rnd_records; - best_key= 0; - best_filter= 0; - if (s->quick && s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE) - best_filter= filter; + best.cost= cur_cost; + best.records_read= org_records; // Records accessed + best.records= records_after_filter; // Records to be checked against + // previous row combinations + + /* + If we are using 'use_cond_selectivity > 1' then + table_after_join_selectivity may take into account other + filters that what is currently used so we have to use + records_after_filter. If 'use_cond_selectivity <= 1 then we + can use information from the best filter. + */ + best.records_after_filter= ((use_cond_selectivity > 1) ? + records_after_filter : + records_best_filter); + best.key= 0; + best.forced_index= forced_index; + /* + filter is only set if + s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE + */ + best.filter= filter; /* range/index_merge/ALL/index access method are "independent", so: */ - best_ref_depends_map= 0; - best_uses_jbuf= MY_TEST(!disable_jbuf && !((s->table->map & + best.ref_depends_map= 0; + best.uses_jbuf= MY_TEST(!disable_jbuf && !((table->map & join->outer_join))); - spl_plan= 0; - best_type= type; + best.spl_plan= 0; + best.type= type; + trace_access_scan.add("chosen", true); } - trace_access_scan.add("chosen", best_key == NULL); + else + trace_access_scan.add("chosen", false); } else { - trace_access_scan.add("type", "scan"); - trace_access_scan.add("chosen", false); - trace_access_scan.add("cause", "cost"); + if (unlikely(trace_access_scan.trace_started())) + trace_access_scan. + add("type", "scan"). + add("chosen", false). + add("cause", "cost"); } + crash_if_first_double_is_bigger(best.records_out, best.records); + crash_if_first_double_is_bigger(best.records_out, best.records_read); + /* Update the cost information for the current partial plan */ - pos->records_read= records; - pos->read_time= best; - pos->key= best_key; - pos->type= best_type; + pos->records_init= best.records_read; + pos->records_after_filter= best.records_after_filter; + pos->records_read= best.records; + pos->records_out= best.records_out; + pos->read_time= best.cost; + pos->key= best.key; + pos->forced_index= best.forced_index; + pos->type= best.type; pos->table= s; - pos->ref_depend_map= best_ref_depends_map; + pos->ref_depend_map= best.ref_depends_map; pos->loosescan_picker.loosescan_key= MAX_KEY; - pos->use_join_buffer= best_uses_jbuf; - pos->spl_plan= spl_plan; - pos->range_rowid_filter_info= best_filter; - pos->key_dependent= (best_type == JT_EQ_REF ? (table_map) 0 : + pos->use_join_buffer= best.uses_jbuf; + pos->spl_plan= best.spl_plan; + pos->range_rowid_filter_info= best.filter; + pos->key_dependent= (best.type == JT_EQ_REF ? (table_map) 0 : key_dependent & remaining_tables); - loose_scan_opt.save_to_position(s, loose_scan_pos); + loose_scan_opt.save_to_position(s, record_count, loose_scan_pos); - if (!best_key && - idx == join->const_tables && - s->table == join->sort_by_table && - join->unit->lim.get_select_limit() >= records) + if (!best.key && + idx == join->const_tables && // First table + table == join->sort_by_table && + join->unit->lim.get_select_limit() >= best.records) // QQQ Why? { trace_access_scan.add("use_tmp_table", true); join->sort_by_table= (TABLE*) 1; // Must use temporary table @@ -8744,7 +9302,7 @@ best_access_path(JOIN *join, trace_paths.end(); if (unlikely(thd->trace_started())) - print_best_access_for_table(thd, pos, best_type); + print_best_access_for_table(thd, pos); DBUG_VOID_RETURN; } @@ -8792,6 +9350,7 @@ static void choose_initial_table_order(JOIN *join) JOIN_TAB **tab= join->best_ref + join->const_tables; JOIN_TAB **tabs_end= tab + join->table_count - join->const_tables; DBUG_ENTER("choose_initial_table_order"); + /* Find where the top-level JOIN_TABs end and subquery JOIN_TABs start */ for (; tab != tabs_end; tab++) { @@ -8872,6 +9431,7 @@ static void choose_initial_table_order(JOIN *join) @param join pointer to the structure providing all context info for the query @param join_tables set of the tables in the query + @param emb_sjm_nest List of tables in case of materialized semi-join nest @retval FALSE ok @@ -8880,13 +9440,14 @@ static void choose_initial_table_order(JOIN *join) */ bool -choose_plan(JOIN *join, table_map join_tables) +choose_plan(JOIN *join, table_map join_tables, TABLE_LIST *emb_sjm_nest) { uint search_depth= join->thd->variables.optimizer_search_depth; uint use_cond_selectivity= join->thd->variables.optimizer_use_condition_selectivity; bool straight_join= MY_TEST(join->select_options & SELECT_STRAIGHT_JOIN); THD *thd= join->thd; + qsort2_cmp jtab_sort_func; DBUG_ENTER("choose_plan"); join->cur_embedding_map= 0; @@ -8894,26 +9455,33 @@ choose_plan(JOIN *join, table_map join_tables) join->prune_level= join->thd->variables.optimizer_prune_level; reset_nj_counters(join, join->join_list); - qsort2_cmp jtab_sort_func; - if (join->emb_sjm_nest) + if ((join->emb_sjm_nest= emb_sjm_nest)) { /* We're optimizing semi-join materialization nest, so put the tables from this semi-join as first */ jtab_sort_func= join_tab_cmp_embedded_first; + /* + If we are searching for the execution plan of a materialized semi-join + nest then allowed_tables contains bits only for the tables from this + nest. + */ + join->allowed_tables= (emb_sjm_nest->sj_inner_tables & + ~join->const_table_map); } else { /* if (SELECT_STRAIGHT_JOIN option is set) reorder tables so dependent tables come after tables they depend - on, otherwise keep tables in the order they were specified in the query + on, otherwise keep tables in the order they were specified in the query else - Apply heuristic: pre-sort all access plans with respect to the number of - records accessed. + Apply heuristic: pre-sort all access plans with respect to the number + of records accessed. */ jtab_sort_func= straight_join ? join_tab_cmp_straight : join_tab_cmp; + join->allowed_tables= ~join->const_table_map; } /* @@ -8924,19 +9492,19 @@ choose_plan(JOIN *join, table_map join_tables) */ my_qsort2(join->best_ref + join->const_tables, join->table_count - join->const_tables, sizeof(JOIN_TAB*), - jtab_sort_func, (void*)join->emb_sjm_nest); + jtab_sort_func, (void*) emb_sjm_nest); Json_writer_object wrapper(thd); Json_writer_array trace_plan(thd,"considered_execution_plans"); - if (!join->emb_sjm_nest) - { + if (!emb_sjm_nest) choose_initial_table_order(join); - } + /* Note: constant tables are already in the join prefix. We don't put them into the cur_sj_inner_tables, though. */ + join->cur_sj_inner_tables= 0; if (straight_join) @@ -8960,14 +9528,7 @@ choose_plan(JOIN *join, table_map join_tables) DBUG_RETURN(TRUE); } - /* - Store the cost of this query into a user variable - Don't update last_query_cost for statements that are not "flat joins" : - i.e. they have subqueries, unions or call stored procedures. - TODO: calculate a correct cost for a query with subqueries and UNIONs. - */ - if (join->thd->lex->is_single_level_stmt()) - join->thd->status_var.last_query_cost= join->best_read; + join->emb_sjm_nest= 0; DBUG_RETURN(FALSE); } @@ -9233,42 +9794,96 @@ optimize_straight_join(JOIN *join, table_map remaining_tables) { POSITION *position= join->positions + idx; Json_writer_object trace_one_table(thd); + double original_record_count, current_record_count; + if (unlikely(thd->trace_started())) - trace_plan_prefix(join, idx, remaining_tables); + trace_plan_prefix(&trace_one_table, join, idx, remaining_tables); /* Find the best access method from 's' to the current partial plan */ best_access_path(join, s, remaining_tables, join->positions, idx, disable_jbuf, record_count, position, &loose_scan_pos); /* Compute the cost of the new plan extended with 's' */ - record_count= COST_MULT(record_count, position->records_read); - const double filter_cmp_gain= position->range_rowid_filter_info - ? position->range_rowid_filter_info->get_cmp_gain(record_count) - : 0; - read_time= COST_ADD(read_time, - COST_ADD(position->read_time - - filter_cmp_gain, - record_count / - TIME_FOR_COMPARE)); - optimize_semi_joins(join, remaining_tables, idx, &record_count, &read_time, - &loose_scan_pos); + current_record_count= COST_MULT(record_count, position->records_out); + read_time= COST_ADD(read_time, position->read_time); + original_record_count= current_record_count; + optimize_semi_joins(join, remaining_tables, idx, ¤t_record_count, + &read_time, &loose_scan_pos); + if (position->sj_strategy != SJ_OPT_NONE && original_record_count) + { + /* Adjust records_out to contain the final number of rows */ + double ratio= current_record_count / original_record_count; + if (ratio < 1) + { + position->records_out*= ratio; + } + if (unlikely(trace_one_table.trace_started())) + { + trace_one_table. + add("sj_rows_out", position->records_out). + add("sj_rows_for_plan", current_record_count). + add("sj_filtered", safe_filtered(position->records_out, + position->records_init)); + } + } remaining_tables&= ~(s->table->map); - double pushdown_cond_selectivity= 1.0; - if (use_cond_selectivity > 1) - pushdown_cond_selectivity= table_cond_selectivity(join, idx, s, - remaining_tables); - position->cond_selectivity= pushdown_cond_selectivity; + if (use_cond_selectivity > 1 && position->sj_strategy == SJ_OPT_NONE) + { + double pushdown_cond_selectivity, records_out; + pushdown_cond_selectivity= table_after_join_selectivity(join, idx, s, + remaining_tables, + &records_out); + if (unlikely(thd->trace_started()) && + pushdown_cond_selectivity != 1.0) + { + trace_one_table. + add("rows_out", records_out). + add("pushdown_cond_selectivity", pushdown_cond_selectivity). + add("filtered", safe_filtered(position->records_out, + position->records_init)); + } + position->cond_selectivity= pushdown_cond_selectivity; + position->records_out= records_out; + current_record_count= COST_MULT(record_count, records_out); + } + else + position->cond_selectivity= 1.0; ++idx; + record_count= current_record_count; } if (join->sort_by_table && join->sort_by_table != join->positions[join->const_tables].table->table) - read_time+= record_count; // We have to make a temp table + { + /* + We may have to make a temp table, note that this is only a + heuristic since we cannot know for sure at this point if we + we are going to use addon fields or to have flush sorting to + disk. We also don't know the temporary table will be in memory + or disk. + The following calculation takes a middle ground where assume + we can sort the keys in memory but have to use a disk based + temporary table to retrive the rows. + This cost is probably much bigger than it has to be... + */ + double sort_cost; + sort_cost= (get_qsort_sort_cost((ha_rows)record_count, 0) + + record_count * + DISK_TEMPTABLE_LOOKUP_COST(thd)); + { + if (unlikely(thd->trace_started())) + { + Json_writer_object trace_one_table(thd); + trace_one_table.add("estimated_cost_for_sorting", sort_cost); + } + } + read_time= COST_ADD(read_time, sort_cost); + } memcpy((uchar*) join->best_positions, (uchar*) join->positions, sizeof(POSITION)*idx); join->join_record_count= record_count; - join->best_read= read_time - COST_EPS; + join->best_read= read_time; } @@ -9370,6 +9985,7 @@ greedy_search(JOIN *join, // ==join->tables or # tables in the sj-mat nest we're optimizing uint n_tables __attribute__((unused)); DBUG_ENTER("greedy_search"); + DBUG_ASSERT(!(remaining_tables & join->const_table_map)); /* number of tables that remain to be optimized */ usable_tables= (join->emb_sjm_nest ? @@ -9458,9 +10074,7 @@ greedy_search(JOIN *join, /* compute the cost of the new plan extended with 'best_table' */ record_count= COST_MULT(record_count, join->positions[idx].records_read); - read_time= COST_ADD(read_time, - COST_ADD(join->positions[idx].read_time, - record_count / TIME_FOR_COMPARE)); + read_time= COST_ADD(read_time, join->positions[idx].read_time); remaining_tables&= ~(best_table->table->map); --size_remain; @@ -9568,9 +10182,7 @@ void JOIN::get_partial_cost_and_fanout(int end_tab_idx, if (tab->records_read && (cur_table_map & filter_map)) { record_count= COST_MULT(record_count, tab->records_read); - read_time= COST_ADD(read_time, - COST_ADD(tab->read_time, - record_count / TIME_FOR_COMPARE)); + read_time= COST_ADD(read_time, tab->read_time); if (tab->emb_sj_nest) sj_inner_fanout= COST_MULT(sj_inner_fanout, tab->records_read); } @@ -9585,7 +10197,7 @@ void JOIN::get_partial_cost_and_fanout(int end_tab_idx, if (tab == end_tab) break; } - *read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE; + *read_time_arg= read_time; *record_count_arg= record_count; } @@ -9614,9 +10226,8 @@ void JOIN::get_prefix_cost_and_fanout(uint n_tables, record_count= COST_MULT(record_count, best_positions[i].records_read); read_time= COST_ADD(read_time, best_positions[i].read_time); } - /* TODO: Take into account condition selectivities here */ } - *read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE; + *read_time_arg= read_time; *record_count_arg= record_count; } @@ -9647,8 +10258,7 @@ double JOIN::get_examined_rows() COST_MULT((double) (tab->get_examined_rows()), prev_fanout)); prev_tab= tab; } - examined_rows= (double) - (records > (double) HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records); + examined_rows= records; return examined_rows; } @@ -9779,28 +10389,31 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, @brief Get the selectivity of conditions when joining a table - @param join The optimized join - @param s The table to be joined for evaluation - @param rem_tables The bitmap of tables to be joined later + @param join The optimized join + @param s The table to be joined for evaluation + @param rem_tables The bitmap of tables to be joined later + @param new_records_out OUT Set to number of rows accepted @detail Get selectivity of conditions that can be applied when joining this table with previous tables. For quick selects and full table scans, selectivity of COND(this_table) - is accounted for in matching_candidates_in_table(). Here, we only count + is accounted for in apply_selectivity_for_table(). Here, we only count selectivity of COND(this_table, previous_tables). For other access methods, we need to calculate selectivity of the whole condition, "COND(this_table) AND COND(this_table, previous_tables)". @retval - selectivity of the conditions imposed on the rows of s + selectivity of the conditions imposed on the rows of s related to + the rows that we are expected to read (position->records_init). */ static -double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, - table_map rem_tables) +double table_after_join_selectivity(JOIN *join, uint idx, JOIN_TAB *s, + table_map rem_tables, + double *new_records_out) { uint16 ref_keyuse_steps_buf[MAX_REF_PARTS]; uint ref_keyuse_size= MAX_REF_PARTS; @@ -9808,13 +10421,14 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, Field *field; TABLE *table= s->table; MY_BITMAP *read_set= table->read_set; - double sel= s->table->cond_selectivity; POSITION *pos= &join->positions[idx]; + double sel, records_out= pos->records_out; uint keyparts= 0; uint found_part_ref_or_null= 0; if (pos->key != 0) { + sel= table->cond_selectivity; /* A ref access or hash join is used for this table. ref access is created from @@ -9863,13 +10477,15 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, { key_part_map quick_key_map= (key_part_map(1) << table->opt_range[key].key_parts) - 1; - if (table->opt_range[key].rows && - !(quick_key_map & ~table->const_key_parts[key])) + if (s->type == JT_RANGE || + (table->opt_range[key].rows && (table->const_key_parts[key] & 1))) { - /* - Ok, there is an equality for each of the key parts used by the - quick select. This means, quick select's estimate can be reused to - discount the selectivity of a prefix of a ref access. + /* + We are either using a range or we are using a REF which the + same key as an active range and the first key part is a constant. + + In both cases we have to discount the selectivity for the range + as otherwise we are using the selectivity twice. */ for (; quick_key_map & 1 ; quick_key_map>>= 1) { @@ -9890,7 +10506,11 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, However if sel becomes greater than 2 then with high probability something went wrong. */ - sel /= (double)table->opt_range[key].rows / (double) table->stat_records(); + DBUG_ASSERT(sel <= 1.0); + DBUG_ASSERT(table->opt_range[key].rows <= + (double) table->stat_records()); + sel /= ((double) table->opt_range[key].rows / + (double) table->stat_records()); set_if_smaller(sel, 1.0); used_range_selectivity= true; } @@ -9984,38 +10604,26 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, } keyuse++; } - } - else - { /* - The table is accessed with full table scan, or quick select. - Selectivity of COND(table) is already accounted for in - matching_candidates_in_table(). + If the field f from the table is equal to a field from one the + earlier joined tables then the selectivity of the range conditions + over the field f must be discounted. + + We need to discount selectivity only if we're using ref-based + access method (and have sel!=1). + If we use ALL/range/index_merge, then sel==1, and no need to discount. */ - sel= 1; - } - - /* - If the field f from the table is equal to a field from one the - earlier joined tables then the selectivity of the range conditions - over the field f must be discounted. - - We need to discount selectivity only if we're using ref-based - access method (and have sel!=1). - If we use ALL/range/index_merge, then sel==1, and no need to discount. - */ - if (pos->key != NULL) - { for (Field **f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) { if (!bitmap_is_set(read_set, field->field_index) || !field->next_equal_field) - continue; - for (Field *next_field= field->next_equal_field; - next_field != field; + continue; + for (Field *next_field= field->next_equal_field; + next_field != field; next_field= next_field->next_equal_field) { - if (!(next_field->table->map & rem_tables) && next_field->table != table) + if (!(next_field->table->map & rem_tables) && + next_field->table != table) { if (field->cond_selectivity > 0) { @@ -10026,11 +10634,37 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, } } } + /* + We have now calculated a more exact 'records_out' taking more index + costs into account. + pos->records_out previously contained the smallest record count for + all range or ref access, which should not be smaller than what we + calculated above. + */ + records_out= pos->records_init * sel; + set_if_smaller(records_out, pos->records_out); } - sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, + sel= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, keyparts, ref_keyuse_steps); + records_out*= sel; + + /* + Update sel to be relative pos->records_read as that is what some old + code expects. Newer code should just use 'position->records_out' instead. + */ + if (pos->records_read == 0) + sel= 1.0; + else + { + sel= records_out / pos->records_read; + DBUG_ASSERT(sel >= 0.0 and sel <= 1.00001); + if (sel > 1.0) + sel= 1.0; + } + exit: + *new_records_out= records_out; if (ref_keyuse_steps != ref_keyuse_steps_buf) my_free(ref_keyuse_steps); return sel; @@ -10051,7 +10685,7 @@ check_if_edge_table(POSITION *pos, if ((pos->type == JT_EQ_REF || (pos->type == JT_REF && - pos->records_read == 1 && + pos->records_init == 1 && !pos->range_rowid_filter_info)) && pushdown_cond_selectivity >= 0.999) return SEARCH_FOUND_EDGE; @@ -10244,7 +10878,7 @@ get_costs_for_tables(JOIN *join, table_map remaining_tables, uint idx, // pplan_cost already too great, stop search continue; - pplan= expand pplan by best_access_method; + pplan= expand plan by best_access_method; remaining_tables= remaining_tables - table T; if (remaining_tables is not an empty set and @@ -10315,8 +10949,8 @@ best_extension_by_limited_search(JOIN *join, { THD *thd= join->thd; /* - 'join' is a partial plan with lower cost than the best plan so far, - so continue expanding it further with the tables in 'remaining_tables'. + 'join' is a partial plan with lower cost than the best plan so far, + so continue expanding it further with the tables in 'remaining_tables'. */ JOIN_TAB *s; double best_record_count= DBL_MAX; @@ -10329,19 +10963,18 @@ best_extension_by_limited_search(JOIN *join, SORT_POSITION *sort= (SORT_POSITION*) alloca(sizeof(SORT_POSITION)*tables_left); SORT_POSITION *sort_end; DBUG_ENTER("best_extension_by_limited_search"); - DBUG_EXECUTE_IF("show_explain_probe_best_ext_lim_search", - if (dbug_user_var_equals_int(thd, + if (dbug_user_var_equals_int(thd, "show_explain_probe_select_id", join->select_lex->select_number)) - dbug_serve_apcs(thd, 1); - ); + dbug_serve_apcs(thd, 1); + ); if (unlikely(thd->check_killed())) // Abort DBUG_RETURN(SEARCH_ABORT); DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time, - "part_plan");); + "part_plan");); status_var_increment(thd->status_var.optimizer_join_prefixes_check_calls); if (join->emb_sjm_nest) @@ -10358,7 +10991,6 @@ best_extension_by_limited_search(JOIN *join, /* allowed_tables is used to check if there are tables left that can improve a key search and to see if there are more tables to add in next iteration. - allowed_current_tables tells us which tables we can add to the current plan at this stage. */ @@ -10372,7 +11004,7 @@ best_extension_by_limited_search(JOIN *join, Json_writer_object trace_one_table(thd); JOIN_TAB **best_ref= join->best_ref + idx; if (unlikely(thd->trace_started())) - trace_plan_prefix(join, idx, remaining_tables); + trace_plan_prefix(&trace_one_table, join, idx, remaining_tables); Json_writer_array arr(thd, "get_costs_for_tables"); @@ -10431,14 +11063,15 @@ best_extension_by_limited_search(JOIN *join, !check_interleaving_with_nj(s)) { table_map real_table_bit= s->table->map; - double current_record_count, current_read_time; + double current_record_count, current_read_time, original_record_count; double partial_join_cardinality; POSITION *position= join->positions + idx, *loose_scan_pos; + double pushdown_cond_selectivity; Json_writer_object trace_one_table(thd); if (unlikely(thd->trace_started())) { - trace_plan_prefix(join, idx, remaining_tables); + trace_plan_prefix(&trace_one_table, join, idx, remaining_tables); trace_one_table.add_table_name(s); } @@ -10447,26 +11080,35 @@ best_extension_by_limited_search(JOIN *join, loose_scan_pos= pos->position+1; /* Compute the cost of the new plan extended with 's' */ - current_record_count= COST_MULT(record_count, position->records_read); - const double filter_cmp_gain= position->range_rowid_filter_info - ? position->range_rowid_filter_info->get_cmp_gain(current_record_count) - : 0; - current_read_time= COST_ADD(read_time, - COST_ADD(position->read_time - - filter_cmp_gain, - current_record_count / - TIME_FOR_COMPARE)); + current_record_count= COST_MULT(record_count, position->records_out); + current_read_time= COST_ADD(read_time, position->read_time); - if (unlikely(thd->trace_started())) + if (unlikely(trace_one_table.trace_started())) { - trace_one_table.add("rows_for_plan", current_record_count); - trace_one_table.add("cost_for_plan", current_read_time); + trace_one_table. + add("rows_for_plan", current_record_count). + add("cost_for_plan", current_read_time); } + original_record_count= current_record_count; optimize_semi_joins(join, remaining_tables, idx, ¤t_record_count, ¤t_read_time, loose_scan_pos); - + if (position->sj_strategy != SJ_OPT_NONE) + { + /* Adjust records_out and current_record_count after semi join */ + double ratio= current_record_count / original_record_count; + if (ratio < 1.0) + position->records_out*= ratio; + if (unlikely(trace_one_table.trace_started())) + { + trace_one_table. + add("sj_rows_out", position->records_out). + add("sj_rows_for_plan", current_record_count). + add("sj_filtered", safe_filtered(position->records_out, + position->records_init)); + } + } /* Expand only partial plans with lower cost than the best QEP so far */ - if (current_read_time >= join->best_read) + if (current_read_time + COST_EPS >= join->best_read) { DBUG_EXECUTE("opt", print_plan(join, idx+1, current_record_count, @@ -10476,7 +11118,7 @@ best_extension_by_limited_search(JOIN *join, trace_one_table .add("pruned_by_cost", true) .add("current_cost", current_read_time) - .add("best_cost", join->best_read + COST_EPS); + .add("best_cost", join->best_read); restore_prev_nj_state(s); restore_prev_sj_state(remaining_tables, s, idx); @@ -10515,19 +11157,19 @@ best_extension_by_limited_search(JOIN *join, if (best_record_count > current_record_count || best_read_time > current_read_time || (idx == join->const_tables && // 's' is the first table in the QEP - s->table == join->sort_by_table)) + s->table == join->sort_by_table)) { /* Store the current record count and cost as the best possible cost at this level if the following holds: - It's the lowest record number and cost so far - - There is no remaing table that could improve index usage - or we found an EQ_REF or REF key with less than 2 - matching records (good enough). + - There is no remaing table that could improve index usage + or we found an EQ_REF or REF key with less than 2 + matching records (good enough). */ if (best_record_count >= current_record_count && best_read_time >= current_read_time && - (!(position->key_dependent & allowed_tables) || + (!(position->key_dependent & join->allowed_tables) || position->records_read < 2.0)) { best_record_count= current_record_count; @@ -10574,28 +11216,41 @@ best_extension_by_limited_search(JOIN *join, } } - double pushdown_cond_selectivity= 1.0; - if (use_cond_selectivity > 1) - pushdown_cond_selectivity= table_cond_selectivity(join, idx, s, - remaining_tables & - ~real_table_bit); + pushdown_cond_selectivity= 1.0; + /* + TODO: When a semi-join strategy is applied (sj_strategy!=SJ_OPT_NONE), + we should account for selectivity from table_after_join_selectivity(). + (Condition filtering is performed before the semi-join removes some + fanout so this might require moving the code around) + */ + if (use_cond_selectivity > 1 && position->sj_strategy == SJ_OPT_NONE) + { + pushdown_cond_selectivity= + table_after_join_selectivity(join, idx, s, + remaining_tables & ~real_table_bit, + &position->records_out); + + if (unlikely(trace_one_table.trace_started()) && + pushdown_cond_selectivity != 1.0) + trace_one_table. + add("pushdown_cond_selectivity", pushdown_cond_selectivity). + add("filtered", safe_filtered(position->records_out, + position->records_init)). + add("rows_out", position->records_out); + } join->positions[idx].cond_selectivity= pushdown_cond_selectivity; - partial_join_cardinality= (current_record_count * - pushdown_cond_selectivity); + partial_join_cardinality= record_count * position->records_out; - if (unlikely(thd->trace_started())) - { - if (pushdown_cond_selectivity < 1.0) - { - trace_one_table.add("selectivity", pushdown_cond_selectivity); - trace_one_table.add("estimated_join_cardinality", - partial_join_cardinality); - } - } + if (unlikely(thd->trace_started()) && pushdown_cond_selectivity < 1.0 && + partial_join_cardinality < current_record_count) + trace_one_table + .add("selectivity", pushdown_cond_selectivity) + .add("estimated_join_cardinality", partial_join_cardinality); + + if (search_depth > 1 && + ((remaining_tables & ~real_table_bit) & join->allowed_tables)) - if ((search_depth > 1) && - ((remaining_tables & ~real_table_bit) & allowed_tables)) { /* Recursively expand the current partial plan */ Json_writer_array trace_rest(thd, "rest_of_plan"); @@ -10633,18 +11288,28 @@ best_extension_by_limited_search(JOIN *join, { /* We may have to make a temp table, note that this is only a - heuristic since we cannot know for sure at this point. - Hence it may be wrong. + heuristic since we cannot know for sure at this point if we + we are going to use addon fields or to have flush sorting to + disk. We also don't know the temporary table will be in memory + or disk. + The following calculation takes a middle ground where assume + we can sort the keys in memory but have to use a disk based + temporary table to retrive the rows. + This cost is probably much bigger than it has to be... */ - trace_one_table.add("cost_for_sorting", current_record_count); - current_read_time= COST_ADD(current_read_time, current_record_count); + double sort_cost; + sort_cost= (get_qsort_sort_cost((ha_rows)current_record_count,0) + + current_record_count * + DISK_TEMPTABLE_LOOKUP_COST(thd)); + trace_one_table.add("cost_for_sorting", sort_cost); + current_read_time= COST_ADD(current_read_time, sort_cost); } if (current_read_time < join->best_read) { memcpy((uchar*) join->best_positions, (uchar*) join->positions, sizeof(POSITION) * (idx + 1)); join->join_record_count= partial_join_cardinality; - join->best_read= current_read_time - COST_EPS; + join->best_read= current_read_time; } DBUG_EXECUTE("opt", print_plan(join, idx+1, current_record_count, @@ -10972,12 +11637,9 @@ prev_record_reads(const POSITION *positions, uint idx, table_map found_ref) is an inprecise estimate and adding 1 (or, in the worst case, #max_nested_outer_joins=64-1) will not make it any more precise. */ - if (pos->records_read) - { - found= COST_MULT(found, pos->records_read); - found*= pos->cond_selectivity; - } - } + if (pos->records_out) + found= COST_MULT(found, pos->records_out); + } } return found; } @@ -11397,16 +12059,20 @@ bool JOIN::get_best_combination() j->table= NULL; //temporary way to tell SJM tables from others. j->ref.key = -1; j->on_expr_ref= (Item**) &null_ptr; - j->keys= key_map(1); /* The unique index is always in 'possible keys' in EXPLAIN */ + /* The unique index is always in 'possible keys' in EXPLAIN */ + j->keys= key_map(1); /* 2. Proceed with processing SJM nest's join tabs, putting them into the sub-order */ SJ_MATERIALIZATION_INFO *sjm= cur_pos->table->emb_sj_nest->sj_mat_info; - j->records_read= (sjm->is_sj_scan? sjm->rows : 1); + j->records_read= (sjm->is_sj_scan? sjm->rows : 1.0); + j->records_init= j->records_out= j->records_read; j->records= (ha_rows) j->records_read; j->cond_selectivity= 1.0; + j->join_read_time= 0.0; /* Not saved currently */ + j->join_loops= 0.0; JOIN_TAB *jt; JOIN_TAB_RANGE *jt_range; if (!(jt= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*sjm->tables)) || @@ -11422,7 +12088,7 @@ bool JOIN::get_best_combination() j= jt; } - *j= *best_positions[tablenr].table; + *j= *cur_pos->table; j->bush_root_tab= sjm_nest_root; @@ -11430,43 +12096,55 @@ bool JOIN::get_best_combination() form->reginfo.join_tab=j; DBUG_PRINT("info",("type: %d", j->type)); if (j->type == JT_CONST) - goto loop_end; // Handled in make_join_stat.. + goto loop_end; // Handled in make_join_stat.. - j->loosescan_match_tab= NULL; //non-nulls will be set later + j->loosescan_match_tab= NULL; //non-nulls will be set later j->inside_loosescan_range= FALSE; j->ref.key = -1; j->ref.key_parts=0; if (j->type == JT_SYSTEM) goto loop_end; - if ( !(keyuse= best_positions[tablenr].key)) + + if (!(keyuse= cur_pos->key)) { - j->type=JT_ALL; - if (best_positions[tablenr].use_join_buffer && + if (cur_pos->type == JT_NEXT) // Forced index + { + j->type= JT_NEXT; + j->index= cur_pos->forced_index; + } + else + j->type= JT_ALL; + if (cur_pos->use_join_buffer && tablenr != const_tables) full_join= 1; } - - /*if (best_positions[tablenr].sj_strategy == SJ_OPT_LOOSE_SCAN) - { - DBUG_ASSERT(!keyuse || keyuse->key == - best_positions[tablenr].loosescan_picker.loosescan_key); - j->index= best_positions[tablenr].loosescan_picker.loosescan_key; - }*/ - if ((j->type == JT_REF || j->type == JT_EQ_REF) && is_hash_join_key_no(j->ref.key)) hash_join= TRUE; - j->range_rowid_filter_info= best_positions[tablenr].range_rowid_filter_info; + j->range_rowid_filter_info= + cur_pos->range_rowid_filter_info; - loop_end: - /* + /* Save records_read in JOIN_TAB so that select_describe()/etc don't have to access join->best_positions[]. */ - j->records_read= best_positions[tablenr].records_read; - j->cond_selectivity= best_positions[tablenr].cond_selectivity; + j->records_init= cur_pos->records_init; + j->records_read= cur_pos->records_read; + j->records_out= cur_pos->records_out; + j->join_read_time= cur_pos->read_time; + j->join_loops= cur_pos->loops; + + loop_end: + j->cond_selectivity= cur_pos->cond_selectivity; + DBUG_ASSERT(j->cond_selectivity <= 1.0); + crash_if_first_double_is_bigger(j->records_out, + j->records_init * + (j->range_rowid_filter_info ? + j->range_rowid_filter_info->selectivity : + 1.0)); + map2table[j->table->tablenr]= j; /* If we've reached the end of sjm nest, switch back to main sequence */ @@ -11730,7 +12408,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, if (!keyparts && allow_full_scan) { /* It's a LooseIndexScan strategy scanning whole index */ - j->type= JT_ALL; + j->type= JT_ALL; // TODO: Check if this should be JT_NEXT j->index= key; DBUG_RETURN(FALSE); } @@ -11859,16 +12537,14 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, j->table->const_table= 1; else if (!((keyparts == keyinfo->user_defined_key_parts && ( - (key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME || - /* Unique key and all keyparts are NULL rejecting */ - ((key_flags & HA_NOSAME) && keyparts == not_null_keyparts) - )) || - /* true only for extended keys */ - (keyparts > keyinfo->user_defined_key_parts && - MY_TEST(key_flags & HA_EXT_NOSAME) && - keyparts == keyinfo->ext_key_parts) - ) || - null_ref_key) + (key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME || + /* Unique key and all keyparts are NULL rejecting */ + ((key_flags & HA_NOSAME) && keyparts == not_null_keyparts) + )) || + /* true only for extended keys */ + (MY_TEST(key_flags & HA_EXT_NOSAME) && + keyparts == keyinfo->ext_key_parts) ) || + null_ref_key) { /* Must read with repeat */ j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF; @@ -12225,7 +12901,10 @@ make_outerjoin_info(JOIN *join) { if (embedding->is_active_sjm()) { - /* We're trying to walk out of an SJ-Materialization nest. Don't do this. */ + /* + We're trying to walk out of an SJ-Materialization nest. + Don't do this. + */ break; } /* Ignore sj-nests: */ @@ -12334,6 +13013,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) DBUG_ENTER("make_join_select"); if (select) { + Json_writer_object trace_wrapper(thd); + Json_writer_object trace_conditions(thd, "attaching_conditions_to_tables"); + Json_writer_array trace_attached_comp(thd, + "attached_conditions_computation"); add_not_null_conds(join); table_map used_tables; /* @@ -12373,8 +13056,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) trace_const_cond.add("condition_on_constant_tables", const_cond); if (const_cond->is_expensive()) { - trace_const_cond.add("evaluated", "false") - .add("cause", "expensive cond"); + if (unlikely(trace_const_cond.trace_started())) + trace_const_cond. + add("evalualted", "false"). + add("cause", "expensive cond"); } else { @@ -12386,8 +13071,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (!const_cond_result) { DBUG_PRINT("info",("Found impossible WHERE condition")); - trace_const_cond.add("evaluated", "true") - .add("found", "impossible where"); + if (unlikely(trace_const_cond.trace_started())) + trace_const_cond. + add("evalualted", "true"). + add("found", "impossible where"); join->exec_const_cond= NULL; DBUG_RETURN(1); } @@ -12406,6 +13093,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond); join->outer_ref_cond= outer_ref_cond; + + Json_writer_object trace(thd); + trace.add("outer_ref_cond", outer_ref_cond); } } else @@ -12421,6 +13111,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) add_cond_and_fix(thd, &pseudo_bits_cond, join->pseudo_bits_cond); join->pseudo_bits_cond= pseudo_bits_cond; + + Json_writer_object trace(thd); + trace.add("pseudo_bits_cond", pseudo_bits_cond); } } } @@ -12429,10 +13122,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) /* Step #2: Extract WHERE/ON parts */ - Json_writer_object trace_wrapper(thd); - Json_writer_object trace_conditions(thd, "attaching_conditions_to_tables"); - Json_writer_array trace_attached_comp(thd, - "attached_conditions_computation"); + uint i; for (i= join->top_join_tab_count - 1; i >= join->const_tables; i--) { @@ -12457,15 +13147,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X */ JOIN_TAB *first_inner_tab= tab->first_inner; + COND *tmp; if (!tab->bush_children) current_map= tab->table->map; else current_map= tab->bush_children->start->emb_sj_nest->sj_inner_tables; - bool use_quick_range=0; - COND *tmp; - /* Tables that are within SJ-Materialization nests cannot have their conditions referring to preceding non-const tables. @@ -12483,23 +13171,28 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) used_tables|=current_map; - if (tab->type == JT_REF && tab->quick && + if ((tab->type == JT_REF || tab->type == JT_RANGE) && tab->quick && (((uint) tab->ref.key == tab->quick->index && tab->ref.key_length < tab->quick->max_used_key_length) || (!is_hash_join_key_no(tab->ref.key) && tab->table->intersect_keys.is_set(tab->ref.key)))) { /* Range uses longer key; Use this instead of ref on key */ - Json_writer_object ref_to_range(thd); - ref_to_range.add("ref_to_range", true); - ref_to_range.add("cause", "range uses longer key"); - tab->type=JT_ALL; - use_quick_range=1; + if (unlikely(thd->trace_started())) + { + Json_writer_object ref_to_range(thd); + ref_to_range. + add("ref_to_range", true). + add("cause", "range uses longer key"); + } + tab->type= JT_RANGE; tab->use_quick=1; tab->ref.key= -1; tab->ref.key_parts=0; // Don't use ref key. - join->best_positions[i].records_read= rows2double(tab->quick->records); - /* + join->best_positions[i].records_read= + join->best_positions[i].records_out= + rows2double(tab->quick->records); + /* We will use join cache here : prevent sorting of the first table only and sort at the end. */ @@ -12557,7 +13250,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (cond && !tmp && tab->quick) { // Outer join - if (tab->type != JT_ALL && !is_hj) + if ((tab->type != JT_ALL && tab->type != JT_RANGE) && !is_hj) { /* Don't use the quick method @@ -12583,7 +13276,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) tab->type == JT_EQ_REF || first_inner_tab) { DBUG_EXECUTE("where",print_where(tmp, - tab->table? tab->table->alias.c_ptr() :"sjm-nest", + tab->table ? + tab->table->alias.c_ptr() :"sjm-nest", QT_ORDINARY);); SQL_SELECT *sel= tab->select= ((SQL_SELECT*) thd->memdup((uchar*) select, @@ -12660,10 +13354,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) sel->quick_keys.clear_all(); sel->needed_reg.clear_all(); if (is_hj && tab->rowid_filter) - { - delete tab->rowid_filter; - tab->rowid_filter= 0; - } + tab->clear_range_rowid_filter(); } else { @@ -12671,20 +13362,22 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } tab->quick=0; } - uint ref_key= sel->head? (uint) sel->head->reginfo.join_tab->ref.key+1 : 0; + uint ref_key= (sel->head ? + (uint) sel->head->reginfo.join_tab->ref.key+1 : + 0); if (i == join->const_tables && ref_key) { if (!tab->const_keys.is_clear_all() && tab->table->reginfo.impossible_range) DBUG_RETURN(1); } - else if (tab->type == JT_ALL && ! use_quick_range) + else if ((tab->type == JT_ALL || tab->type == JT_NEXT)) { if (!tab->const_keys.is_clear_all() && tab->table->reginfo.impossible_range) DBUG_RETURN(1); // Impossible range /* - We plan to scan all rows. + We plan to scan all rows either with table or index scan Check again if we should use an index. There are two cases: @@ -12704,7 +13397,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (!tab->table->is_filled_at_execution() && !tab->loosescan_match_tab && // (1) - ((cond && (!tab->keys.is_subset(tab->const_keys) && i > 0)) || + ((cond && (!tab->keys.is_subset(tab->const_keys) && + i > join->const_tables)) || (!tab->const_keys.is_clear_all() && i == join->const_tables && join->unit->lim.get_select_limit() < join->best_positions[i].records_read && @@ -12755,7 +13449,23 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) /* Fix for EXPLAIN */ if (sel->quick) - join->best_positions[i].records_read= (double)sel->quick->records; + { + join->best_positions[i].records_read= + (double) sel->quick->records; + set_if_smaller(join->best_positions[i].records_out, + join->best_positions[i].records_read); + } + else + { + /* + sel->head->opt_range_condition_rows may have been updated to a smaller number than + before by a call to test_quick_select. This can happen even if the range optimizer + decided to not use the range (sel->quick was not set). + */ + set_if_smaller(join->best_positions[i].records_out, + rows2double(sel->head->opt_range_condition_rows)); + + } } else { @@ -12765,6 +13475,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (!sel->quick_keys.is_subset(tab->checked_keys) || !sel->needed_reg.is_subset(tab->checked_keys)) { + handler *file= tab->table->file; /* "Range checked for each record" is a "last resort" access method that should only be used when the other option is a cross-product @@ -12780,9 +13491,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) (sel->quick_keys.is_clear_all() || (sel->quick && sel->quick->read_time > - tab->table->file->scan_time() + - tab->table->file->stats.records/TIME_FOR_COMPARE - ))) ? + file->cost(file->ha_scan_and_compare_time(tab->table->file-> stats.records))))) ? 2 : 1; sel->read_tables= used_tables & ~current_map; sel->quick_keys.clear_all(); @@ -13003,7 +13712,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) Item *const cond = tab->select_cond; Json_writer_object trace_one_table(thd); trace_one_table.add_table_name(tab); - trace_one_table.add("attached", cond); + trace_one_table.add("attached_condition", cond); } } } @@ -13122,36 +13831,45 @@ bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys) static bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array) { - KEYUSE *keyuse= dynamic_element(keyuse_array, 0, KEYUSE*); + KEYUSE *keyuse, *end_keyuse; size_t elements= keyuse_array->elements; TABLE *prev_table= 0; - for (size_t i= 0; i < elements; i++, keyuse++) + + DBUG_ASSERT(elements > 0); + /* The last element is an end marker */ + DBUG_ASSERT(dynamic_element(keyuse_array, elements-1, + KEYUSE*)[0].table == 0); + + for (keyuse= dynamic_element(keyuse_array, 0, KEYUSE*), + end_keyuse= keyuse + elements - 1; + keyuse < end_keyuse; + keyuse++) { - if (!keyuse->table) - break; + DBUG_ASSERT(keyuse->table); + KEYUSE *first_table_keyuse= NULL; table_map last_used_tables= 0; uint count= 0; uint keys= 0; TABLE_LIST *derived= NULL; + if (keyuse->table != prev_table) derived= keyuse->table->pos_in_table_list; - while (derived && derived->is_materialized_derived()) + + if (!derived->is_materialized_derived()) + continue; + + for (;;) { if (keyuse->table != prev_table) { prev_table= keyuse->table; while (keyuse->table == prev_table && keyuse->key != MAX_KEY) - { keyuse++; - i++; - } if (keyuse->table != prev_table) { keyuse--; - i--; - derived= NULL; - continue; + break; } first_table_keyuse= keyuse; last_used_tables= keyuse->used_tables; @@ -13165,14 +13883,12 @@ bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array) } count++; keyuse++; - i++; if (keyuse->table != prev_table) { if (generate_derived_keys_for_table(first_table_keyuse, count, ++keys)) return TRUE; keyuse--; - i--; - derived= NULL; + break; } } } @@ -13211,9 +13927,12 @@ void JOIN::drop_unused_derived_keys() if (tab->ref.key >= 0 && tab->ref.key < MAX_KEY) tab->ref.key= 0; else + { tmp_tbl->s->keys= 0; + tmp_tbl->s->uniques= 0; + } } - tab->keys= (key_map) (tmp_tbl->s->keys ? 1 : 0); + tab->keys= (key_map) (tmp_tbl->s->keys || tmp_tbl->s->uniques ? 1 : 0); } } @@ -13323,6 +14042,7 @@ void set_join_cache_denial(JOIN_TAB *join_tab) don't do join buffering for the first table in sjm nest. */ join_tab[-1].next_select= sub_select; + join_tab[-1].cached_pfs_batch_update= join_tab[-1].pfs_batch_update(); if (join_tab->type == JT_REF && join_tab->is_ref_for_hash_join()) { join_tab->type= JT_ALL; @@ -13643,7 +14363,6 @@ uint check_join_cache_usage(JOIN_TAB *tab, uint table_index, JOIN_TAB *prev_tab) { - Cost_estimate cost; uint flags= 0; ha_rows rows= 0; uint bufsz= 4096; @@ -13778,7 +14497,9 @@ uint check_join_cache_usage(JOIN_TAB *tab, prev_cache= prev_tab->cache; switch (tab->type) { + case JT_NEXT: case JT_ALL: + case JT_RANGE: if (cache_level == 1) prev_cache= 0; if ((tab->cache= new (root) JOIN_CACHE_BNL(join, tab, prev_cache))) @@ -13801,6 +14522,8 @@ uint check_join_cache_usage(JOIN_TAB *tab, if (!tab->is_ref_for_hash_join() && !no_bka_cache) { + Cost_estimate cost; + cost.reset(); flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT; if (tab->table->covering_keys.is_set(tab->ref.key)) flags|= HA_MRR_INDEX_ONLY; @@ -13859,7 +14582,7 @@ uint check_join_cache_usage(JOIN_TAB *tab, } no_join_cache: - if (tab->type != JT_ALL && tab->is_ref_for_hash_join()) + if (tab->type != JT_ALL && tab->type != JT_RANGE && tab->is_ref_for_hash_join()) { tab->type= JT_ALL; tab->ref.key_parts= 0; @@ -13939,7 +14662,9 @@ restart: case JT_EQ_REF: case JT_REF: case JT_REF_OR_NULL: + case JT_NEXT: case JT_ALL: + case JT_RANGE: tab->used_join_cache_level= check_join_cache_usage(tab, options, no_jbuf_after, idx, @@ -14075,6 +14800,9 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) uint i; DBUG_ENTER("make_join_readinfo"); + Json_writer_object trace_wrapper(join->thd); + Json_writer_array trace_arr(join->thd, "make_join_readinfo"); + bool statistics= MY_TEST(!(join->select_options & SELECT_DESCRIBE)); bool sorted= 1; @@ -14104,18 +14832,21 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) if (tab->bush_root_tab && tab->bush_root_tab->bush_children->start == tab) prev_tab= NULL; - DBUG_ASSERT(tab->bush_children || tab->table == join->best_positions[i].table->table); + DBUG_ASSERT(tab->bush_children || + tab->table == join->best_positions[i].table->table); tab->partial_join_cardinality= join->best_positions[i].records_read * - (prev_tab? prev_tab->partial_join_cardinality : 1); + (prev_tab ? + prev_tab->partial_join_cardinality : 1); if (!tab->bush_children) i++; } check_join_cache_usage_for_tables(join, options, no_jbuf_after); - + JOIN_TAB *first_tab; - for (tab= first_tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); + for (tab= first_tab= first_linear_tab(join, + WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); tab; tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) { @@ -14141,10 +14872,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) */ if (!(tab->bush_root_tab && tab->bush_root_tab->bush_children->end == tab + 1)) - { - tab->next_select=sub_select; /* normal select */ - } - + tab->next_select= sub_select; /* normal select */ if (tab->loosescan_match_tab) { @@ -14193,13 +14921,35 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) (!jcl || jcl > 4) && !tab->ref.is_access_triggered()) push_index_cond(tab, tab->ref.key); break; + case JT_NEXT: // Index scan + DBUG_ASSERT(!(tab->select && tab->select->quick)); + if (tab->use_quick == 2) + { + join->thd->set_status_no_good_index_used(); + tab->read_first_record= join_init_quick_read_record; + if (statistics) + join->thd->inc_status_select_range_check(); + } + else + { + tab->read_first_record= join_read_first; + if (statistics) + { + join->thd->inc_status_select_scan(); + join->thd->query_plan_flags|= QPLAN_FULL_SCAN; + } + } + break; case JT_ALL: + case JT_RANGE: case JT_HASH: + { + bool have_quick_select= tab->select && tab->select->quick; /* If previous table use cache If the incoming data set is already sorted don't use cache. Also don't use cache if this is the first table in semi-join - materialization nest. + materialization nest. */ /* These init changes read_record */ if (tab->use_quick == 2) @@ -14232,7 +14982,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) } else { - if (tab->select && tab->select->quick) + if (have_quick_select) { if (statistics) join->thd->inc_status_select_full_range_join(); @@ -14249,41 +14999,27 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) } if (!table->no_keyread) { - if (!(tab->select && tab->select->quick && - tab->select->quick->index != MAX_KEY && //not index_merge - table->covering_keys.is_set(tab->select->quick->index)) && - (!table->covering_keys.is_clear_all() && - !(tab->select && tab->select->quick))) + if (!(have_quick_select && + tab->select->quick->index != MAX_KEY && //not index_merge + table->covering_keys.is_set(tab->select->quick->index)) && + (!table->covering_keys.is_clear_all() && ! have_quick_select)) { // Only read index tree if (tab->loosescan_match_tab) tab->index= tab->loosescan_key; else - { -#ifdef BAD_OPTIMIZATION - /* - It has turned out that the below change, while speeding things - up for disk-bound loads, slows them down for cases when the data - is in disk cache (see BUG#35850): - See bug #26447: "Using the clustered index for a table scan - is always faster than using a secondary index". - */ - if (table->file->pk_is_clustering_key(table->s->primary_key)) - tab->index= table->s->primary_key; - else -#endif - tab->index=find_shortest_key(table, & table->covering_keys); - } + tab->index= tab->cached_covering_key; tab->read_first_record= join_read_first; /* Read with index_first / index_next */ - tab->type= tab->type == JT_ALL ? JT_NEXT : JT_HASH_NEXT; + tab->type= tab->type == JT_ALL ? JT_NEXT : JT_HASH_NEXT; } } - if (tab->select && tab->select->quick && + if (have_quick_select && tab->select->quick->index != MAX_KEY && !tab->table->covering_keys.is_set(tab->select->quick->index)) push_index_cond(tab, tab->select->quick->index); } break; + } case JT_FT: break; /* purecov: begin deadcode */ @@ -14295,6 +15031,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) abort(); /* purecov: end */ } + tab->cached_pfs_batch_update= tab->pfs_batch_update(); DBUG_EXECUTE("where", char buff[256]; @@ -14385,7 +15122,7 @@ bool error_if_full_join(JOIN *join) for (JOIN_TAB *tab=first_top_level_tab(join, WITH_CONST_TABLES); tab; tab= next_top_level_tab(join, tab)) { - if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) + if ((tab->type == JT_ALL || tab->type == JT_NEXT)) { my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER_THD(join->thd, @@ -14397,37 +15134,58 @@ bool error_if_full_join(JOIN *join) } -void JOIN_TAB::build_range_rowid_filter_if_needed() -{ - if (rowid_filter && !is_rowid_filter_built) - { - /** - The same handler object (table->file) is used to build a filter - and to perfom a primary table access (by the main query). +/** + build_range_rowid_filter() - To estimate the time for filter building tracker should be changed - and after building of the filter has been finished it should be - switched back to the previos tracker. - */ - Exec_time_tracker *table_tracker= table->file->get_time_tracker(); - Rowid_filter_tracker *rowid_tracker= rowid_filter->get_tracker(); - table->file->set_time_tracker(rowid_tracker->get_time_tracker()); - rowid_tracker->start_tracking(join->thd); - if (!rowid_filter->build()) - { - is_rowid_filter_built= true; - } - else - { - delete rowid_filter; - rowid_filter= 0; - } - rowid_tracker->stop_tracking(join->thd); - table->file->set_time_tracker(table_tracker); + Build range rowid filter. This function should only be called if + need_to_build_rowid_filter + is true +*/ + +void JOIN_TAB::build_range_rowid_filter() +{ + DBUG_ASSERT(need_to_build_rowid_filter && rowid_filter); + + /** + The same handler object (table->file) is used to build a filter + and to perfom a primary table access (by the main query). + + To estimate the time for filter building tracker should be changed + and after building of the filter has been finished it should be + switched back to the previos tracker. + */ + + Exec_time_tracker *table_tracker= table->file->get_time_tracker(); + Rowid_filter_tracker *rowid_tracker= rowid_filter->get_tracker(); + table->file->set_time_tracker(rowid_tracker->get_time_tracker()); + rowid_tracker->start_tracking(join->thd); + + if (rowid_filter->build()) + { + /* Failed building rowid filter */ + clear_range_rowid_filter(); } + need_to_build_rowid_filter= false; + rowid_tracker->stop_tracking(join->thd); + table->file->set_time_tracker(table_tracker); } +/* + Clear used rowid filter + + Note that rowid_filter is allocated on mem_root and not really freed! + Only the rowid data is freed. +*/ + +void JOIN_TAB::clear_range_rowid_filter() +{ + delete rowid_filter; + rowid_filter= 0; + need_to_build_rowid_filter= false; + range_rowid_filter_info= 0; +} + /** cleanup JOIN_TAB. @@ -14448,10 +15206,7 @@ void JOIN_TAB::cleanup() delete quick; quick= 0; if (rowid_filter) - { - delete rowid_filter; - rowid_filter= 0; - } + clear_range_rowid_filter(); if (cache) { cache->free(); @@ -14497,7 +15252,7 @@ void JOIN_TAB::cleanup() end_read_record(&read_record); tmp->jtbm_subselect->cleanup(); /* - The above call freed the materializedd temptable. Set it to NULL so + The above call freed the materialized temptable. Set it to NULL so that we don't attempt to touch it if JOIN_TAB::cleanup() is invoked multiple times (it may be) */ @@ -14520,56 +15275,97 @@ void JOIN_TAB::cleanup() /** Estimate the time to get rows of the joined table + + Updates found_records, records, cached_covering_key, read_time and + cache_scan_and_compare_time */ -double JOIN_TAB::scan_time() +void JOIN_TAB::estimate_scan_time() { - double res; + THD *thd= join->thd; + handler *file= table->file; + double copy_cost; + + cached_covering_key= MAX_KEY; if (table->is_created()) { if (table->is_filled_at_execution()) { get_delayed_table_estimates(table, &records, &read_time, - &startup_cost); - found_records= records; + &startup_cost); table->opt_range_condition_rows= records; + table->used_stat_records= records; + copy_cost= file->ROW_COPY_COST; } else { - found_records= records= table->stat_records(); - read_time= table->file->scan_time(); + records= table->stat_records(); /* table->opt_range_condition_rows has already been set to table->file->stats.records */ + DBUG_ASSERT(table->opt_range_condition_rows == records); + + if (!table->covering_keys.is_clear_all() && ! table->no_keyread) + { + cached_covering_key= find_shortest_key(table, &table->covering_keys); + read_time= file->cost(file->ha_key_scan_time(cached_covering_key, + records)); + copy_cost= 0; // included in ha_key_scan_time + } + else + { + read_time= file->cost(file->ha_scan_time(records)); + copy_cost= 0; + } } - res= read_time; } else { - found_records= records=table->stat_records(); - read_time= found_records ? (double)found_records: 10.0;// TODO:fix this stub - res= read_time; + /* + The following is same as calling + TABLE_SHARE::update_optimizer_costs, but without locks + */ + if (table->s->db_type() == heap_hton) + memcpy(&table->s->optimizer_costs, &heap_optimizer_costs, + sizeof(heap_optimizer_costs)); + else + memcpy(&table->s->optimizer_costs, &tmp_table_optimizer_costs, + sizeof(tmp_table_optimizer_costs)); + file->set_optimizer_costs(thd); + table->s->optimizer_costs_inited=1; + + records= table->stat_records(); + DBUG_ASSERT(table->opt_range_condition_rows == records); + // Needs fix.. + read_time= file->cost(table->file->ha_scan_time(MY_MAX(records, 1000))); + copy_cost= table->s->optimizer_costs.row_copy_cost; } - return res; + + found_records= records; + cached_scan_and_compare_time= (read_time + records * + (copy_cost + WHERE_COST_THD(thd))); } /** - Estimate the number of rows that a an access method will read from a table. + Estimate the number of rows that an access method will read from a table. - @todo: why not use JOIN_TAB::found_records + @todo: why not use JOIN_TAB::found_records or JOIN_TAB::records_read */ -ha_rows JOIN_TAB::get_examined_rows() +double JOIN_TAB::get_examined_rows() { double examined_rows; SQL_SELECT *sel= filesort? filesort->select : this->select; if (sel && sel->quick && use_quick != 2) - examined_rows= (double)sel->quick->records; - else if (type == JT_NEXT || type == JT_ALL || - type == JT_HASH || type ==JT_HASH_NEXT) + { + examined_rows= (double) sel->quick->records; + DBUG_ASSERT(examined_rows == sel->quick->records); + } + else if (type == JT_NEXT || type == JT_ALL || type == JT_RANGE || + type == JT_HASH || type == JT_HASH_NEXT) { if (limit) { @@ -14594,11 +15390,11 @@ ha_rows JOIN_TAB::get_examined_rows() } } else - examined_rows= records_read; + examined_rows= records_init; if (examined_rows >= (double) HA_ROWS_MAX) - return HA_ROWS_MAX; - return (ha_rows) examined_rows; + return (double) HA_ROWS_MAX; + return examined_rows; } @@ -14608,6 +15404,7 @@ ha_rows JOIN_TAB::get_examined_rows() TODO: consider moving this together with join_tab_execution_startup */ + bool JOIN_TAB::preread_init() { TABLE_LIST *derived= table->pos_in_table_list; @@ -14649,7 +15446,31 @@ bool JOIN_TAB::preread_init() } -bool JOIN_TAB::pfs_batch_update(JOIN *join) +/** + pfs_batch_update() + + Check if the used table will do a lot of read calls in a row without + any intervening read calls to any other tables. + + @return 0 No + @return 1 Yes + + If yes, then the handler will be informed about this with the + start_psi_batch_mode() / end_psi_batch_mode() calls + + This is currently used only to speed up performance schema code for + multiple reads. + + In the future we may also inform the engine about this. The engine + could use this information to cache the used pages, keep blocks + locked in the page cache and similar things to speed up repeated + reads. + + The return value of this function is cached in + JOIN_TAB::cached_pfs_batch_update +*/ + +bool JOIN_TAB::pfs_batch_update() { /* Use PFS batch mode if @@ -14984,7 +15805,6 @@ void JOIN::cleanup(bool full) if (current_ref_ptrs != items0) { set_items_ref_array(items0); - set_group_rpa= false; } DBUG_VOID_RETURN; } @@ -16494,7 +17314,7 @@ static COND *build_equal_items(JOIN *join, COND *cond, table->on_expr= build_equal_items(join, table->on_expr, inherited, nested_join_list, ignore_on_conds, &table->cond_equal); - if (unlikely(join->thd->trace_started())) + if (unlikely(thd->trace_started())) { const char *table_name; if (table->nested_join) @@ -17887,25 +18707,28 @@ static bool check_interleaving_with_nj(JOIN_TAB *next_tab) Do update counters for "pairs of brackets" that we've left (marked as X,Y,Z in the above picture) */ - for (;next_emb && next_emb != join->emb_sjm_nest; next_emb= next_emb->embedding) + for (;next_emb && next_emb != join->emb_sjm_nest; + next_emb= next_emb->embedding) { if (!next_emb->sj_on_expr) { next_emb->nested_join->counter++; if (next_emb->nested_join->counter == 1) { - /* + /* next_emb is the first table inside a nested join we've "entered". In - the picture above, we're looking at the 'X' bracket. Don't exit yet as - X bracket might have Y pair bracket. + the picture above, we're looking at the 'X' bracket. Don't exit yet + as X bracket might have Y pair bracket. */ join->cur_embedding_map |= next_emb->nested_join->nj_map; } + DBUG_ASSERT(next_emb->nested_join->n_tables >= + next_emb->nested_join->counter); + if (next_emb->nested_join->n_tables != next_emb->nested_join->counter) break; - /* We're currently at Y or Z-bracket as depicted in the above picture. Mark that we've left it and continue walking up the brackets hierarchy. @@ -18119,7 +18942,7 @@ table_map JOIN::get_allowed_nj_tables(uint idx) first_alt TRUE <=> Use the LooseScan plan for the first_tab no_jbuf_before Don't allow to use join buffering before this table - reopt_rec_count OUT New output record count + outer_rec_count OUT New output record count reopt_cost OUT New join prefix cost DESCRIPTION @@ -18174,6 +18997,8 @@ void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab, table_map save_cur_sj_inner_tables= join->cur_sj_inner_tables; join->cur_sj_inner_tables= 0; + double inner_fanout= 1.0; + for (i= first_tab; i <= last_tab; i++) { JOIN_TAB *rs= join->positions[i].table; @@ -18186,34 +19011,54 @@ void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab, join->positions, i, TRUE, rec_count, &pos, &loose_scan_pos); + if ((i == first_tab && first_alt)) + pos= loose_scan_pos; } else pos= join->positions[i]; - if ((i == first_tab && first_alt)) - pos= loose_scan_pos; - reopt_remaining_tables &= ~rs->table->map; - rec_count= COST_MULT(rec_count, pos.records_read); cost= COST_ADD(cost, pos.read_time); - cost= COST_ADD(cost, rec_count / TIME_FOR_COMPARE); - //TODO: take into account join condition selectivity here - double pushdown_cond_selectivity= 1.0; - table_map real_table_bit= rs->table->map; - if (join->thd->variables.optimizer_use_condition_selectivity > 1) - { - pushdown_cond_selectivity= table_cond_selectivity(join, i, rs, - reopt_remaining_tables & - ~real_table_bit); - } - (*outer_rec_count) *= pushdown_cond_selectivity; - if (!rs->emb_sj_nest) - *outer_rec_count= COST_MULT(*outer_rec_count, pos.records_read); + double records_out= pos.records_out; + /* + The (i != last_tab) is here to mimic what + best_extension_by_limited_search() does: do not call + table_after_join_selectivity() for the join_tab where the semi-join + strategy is applied + */ + if (i != last_tab && + join->thd->variables.optimizer_use_condition_selectivity > 1) + { + table_map real_table_bit= rs->table->map; + double __attribute__((unused)) pushdown_cond_selectivity; + pushdown_cond_selectivity= + table_after_join_selectivity(join, i, rs, + reopt_remaining_tables & + ~real_table_bit, &records_out); + } + rec_count= COST_MULT(rec_count, records_out); + *outer_rec_count= COST_MULT(*outer_rec_count, records_out); + + if (rs->emb_sj_nest) + inner_fanout= COST_MULT(inner_fanout, records_out); } + + /* Discount the fanout produced by the subquery */ + if (inner_fanout > 1.0) + *outer_rec_count /= inner_fanout; + join->cur_sj_inner_tables= save_cur_sj_inner_tables; *reopt_cost= cost; + if (rec_count < *outer_rec_count) + { + /* + The tables inside the subquery produce smaller fanout than outer tables. + This can happen in edge cases. + */ + *outer_rec_count= rec_count; + } } @@ -18246,8 +19091,11 @@ optimize_cond(JOIN *join, COND *conds, Json_writer_object trace_wrapper(thd); Json_writer_object trace_cond(thd, "condition_processing"); - trace_cond.add("condition", join->conds == conds ? "WHERE" : "HAVING") - .add("original_condition", conds); + + if (unlikely(trace_cond.trace_started())) + trace_cond. + add("condition", join->conds == conds ? "WHERE" : "HAVING"). + add("original_condition", conds); Json_writer_array trace_steps(thd, "steps"); DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY);); @@ -18255,10 +19103,13 @@ optimize_cond(JOIN *join, COND *conds, ignore_on_conds, cond_equal, MY_TEST(flags & OPT_LINK_EQUAL_FIELDS)); DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY);); + + if (unlikely(thd->trace_started())) { Json_writer_object equal_prop_wrapper(thd); - equal_prop_wrapper.add("transformation", "equality_propagation") - .add("resulting_condition", conds); + equal_prop_wrapper. + add("transformation", "equality_propagation"). + add("resulting_condition", conds); } /* change field = field to field = const for each found field = const */ @@ -18268,20 +19119,24 @@ optimize_cond(JOIN *join, COND *conds, Remove all and-levels where CONST item != CONST item */ DBUG_EXECUTE("where",print_where(conds,"after const change", QT_ORDINARY);); + if (unlikely(thd->trace_started())) { Json_writer_object const_prop_wrapper(thd); - const_prop_wrapper.add("transformation", "constant_propagation") - .add("resulting_condition", conds); + const_prop_wrapper. + add("transformation", "constant_propagation"). + add("resulting_condition", conds); } conds= conds->remove_eq_conds(thd, cond_value, true); if (conds && conds->type() == Item::COND_ITEM && ((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC) *cond_equal= &((Item_cond_and*) conds)->m_cond_equal; + if (unlikely(thd->trace_started())) { Json_writer_object cond_removal_wrapper(thd); - cond_removal_wrapper.add("transformation", "trivial_condition_removal") - .add("resulting_condition", conds); + cond_removal_wrapper. + add("transformation", "trivial_condition_removal"). + add("resulting_condition", conds); } DBUG_EXECUTE("info",print_where(conds,"after remove", QT_ORDINARY);); } @@ -18498,7 +19353,7 @@ bool cond_is_datetime_is_null(Item *cond) => SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR ((b = 5) AND (a = 5))) AND (b = 5) AND (a = 5) - After this an additional call of remove_eq_conds() converts it to + After this an additional call of remove_eq_conds() converts it to => SELECT * FROM t1 WHERE (b = 5) AND (a = 5) */ @@ -18611,7 +19466,7 @@ Item_cond::remove_eq_conds(THD *thd, Item::cond_result *cond_value, else { if (new_item->type() == Item::COND_ITEM && - ((Item_cond*) new_item)->functype() == functype()) + ((Item_cond*) new_item)->functype() == functype()) { List *new_item_arg_list= ((Item_cond *) new_item)->argument_list(); @@ -19587,6 +20442,7 @@ TABLE *Create_tmp_table::start(THD *thd, sizeof(*m_key_part_info)*(param->group_parts+1), ¶m->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4), + ¶m->rec_per_key, sizeof(ulong)*param->group_parts, &tmpname, (uint) strlen(path)+1, &m_group_buff, (m_group && ! m_using_unique_constraint ? param->group_length : 0), @@ -19911,7 +20767,7 @@ bool Create_tmp_table::finalize(THD *thd, bool save_abort_on_warning; uchar *pos; uchar *null_flags; - KEY *keyinfo; + KEY *keyinfo= param->keyinfo; TMP_ENGINE_COLUMNDEF *recinfo; TABLE_SHARE *share= table->s; Copy_field *copy= param->copy_field; @@ -20103,12 +20959,10 @@ bool Create_tmp_table::finalize(THD *thd, set_if_smaller(share->max_rows, m_rows_limit); param->end_write_records= m_rows_limit; - keyinfo= param->keyinfo; - if (m_group) { DBUG_PRINT("info",("Creating group key in temporary table")); - table->group= m_group; /* Table is grouped by key */ + table->group= m_group; /* Table is grouped by key */ param->group_buff= m_group_buff; share->keys=1; share->uniques= MY_TEST(m_using_unique_constraint); @@ -20118,15 +20972,18 @@ bool Create_tmp_table::finalize(THD *thd, keyinfo->key_part= m_key_part_info; keyinfo->flags=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY; keyinfo->ext_key_flags= keyinfo->flags; - keyinfo->usable_key_parts=keyinfo->user_defined_key_parts= param->group_parts; + keyinfo->usable_key_parts=keyinfo->user_defined_key_parts= + param->group_parts; keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; + share->ext_key_parts= share->key_parts= keyinfo->ext_key_parts; keyinfo->key_length=0; - keyinfo->rec_per_key=NULL; + keyinfo->rec_per_key= param->rec_per_key; keyinfo->read_stats= NULL; keyinfo->collected_stats= NULL; keyinfo->algorithm= HA_KEY_ALG_UNDEF; keyinfo->is_statistics_from_stat_tables= FALSE; keyinfo->name= group_key; + keyinfo->comment.str= 0; ORDER *cur_group= m_group; for (; cur_group ; cur_group= cur_group->next, m_key_part_info++) { @@ -20227,6 +21084,7 @@ bool Create_tmp_table::finalize(THD *thd, keyinfo->usable_key_parts= keyinfo->user_defined_key_parts; table->distinct= 1; share->keys= 1; + share->ext_key_parts= share->key_parts= keyinfo->ext_key_parts; if (!(m_key_part_info= (KEY_PART_INFO*) alloc_root(&table->mem_root, keyinfo->user_defined_key_parts * sizeof(KEY_PART_INFO)))) @@ -20331,6 +21189,8 @@ bool Create_tmp_table::finalize(THD *thd, m_key_part_info++; } } + if (share->keys) + keyinfo->index_flags= table->file->index_flags(0, 0, 1); if (unlikely(thd->is_fatal_error)) // If end of memory goto err; /* purecov: inspected */ @@ -20445,7 +21305,7 @@ TABLE *create_tmp_table_for_schema(THD *thd, TMP_TABLE_PARAM *param, { TABLE *table; Create_tmp_table maker((ORDER *) NULL, false, false, - select_options, HA_POS_ERROR); + select_options, HA_ROWS_MAX); if (!(table= maker.start(thd, param, &table_alias)) || maker.add_schema_fields(thd, table, param, schema_table) || maker.finalize(thd, table, param, do_not_open, keep_row_order)) @@ -20625,7 +21485,6 @@ bool Virtual_tmp_table::sp_set_all_fields_from_item(THD *thd, Item *value) return false; } - bool open_tmp_table(TABLE *table) { int error; @@ -20639,6 +21498,7 @@ bool open_tmp_table(TABLE *table) } table->db_stat= HA_OPEN_KEYFILE; (void) table->file->extra(HA_EXTRA_QUICK); /* Faster */ + table->file->set_optimizer_costs(table->in_use); if (!table->is_created()) { table->set_created(); @@ -20721,6 +21581,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, /* Can't create a key; Make a unique constraint instead of a key */ share->keys= 0; + share->key_parts= share->ext_key_parts= 0; share->uniques= 1; using_unique_constraint=1; bzero((char*) &uniquedef,sizeof(uniquedef)); @@ -20785,6 +21646,8 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, keydef.flag|= HA_NULL_ARE_EQUAL; } } + if (share->keys) + keyinfo->index_flags= table->file->index_flags(0, 0, 1); } bzero((char*) &create_info,sizeof(create_info)); create_info.data_file_length= table->in_use->variables.tmp_disk_table_size; @@ -20915,6 +21778,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, { /* Can't create a key; Make a unique constraint instead of a key */ share->keys= 0; + share->key_parts= share->ext_key_parts= 0; share->uniques= 1; using_unique_constraint=1; bzero((char*) &uniquedef,sizeof(uniquedef)); @@ -20978,6 +21842,8 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, keydef.flag|= HA_NULL_ARE_EQUAL; } } + if (share->keys) + keyinfo->index_flags= table->file->index_flags(0, 0, 1); } MI_CREATE_INFO create_info; bzero((char*) &create_info,sizeof(create_info)); @@ -21029,6 +21895,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, TABLE_SHARE share; const char *save_proc_info; int write_err= 0; + String tmp_alias; DBUG_ENTER("create_internal_tmp_table_from_heap"); if (is_duplicate) *is_duplicate= FALSE; @@ -21121,9 +21988,18 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, plugin_unlock(0, table->s->db_plugin); share.db_plugin= my_plugin_lock(0, share.db_plugin); new_table.s= table->s; // Keep old share + + /* + The following work with alias has to be done as new_table.alias() may have + been reallocated and we want to keep the original one. + */ + tmp_alias.move(table->alias); *table= new_table; + table->alias.move(tmp_alias); + new_table.alias.free(); + /* Get the new share */ *table->s= share; - + table->file->change_table_ptr(table, table->s); table->use_all_columns(); if (save_proc_info) @@ -21314,6 +22190,7 @@ do_select(JOIN *join, Procedure *procedure) { int rc= 0; enum_nested_loop_state error= NESTED_LOOP_OK; + uint top_level_tables= join->exec_join_tab_cnt(); DBUG_ENTER("do_select"); if (join->pushdown_query) @@ -21330,8 +22207,9 @@ do_select(JOIN *join, Procedure *procedure) if (join->pushdown_query->store_data_in_temp_table) { - JOIN_TAB *last_tab= join->join_tab + join->exec_join_tab_cnt(); + JOIN_TAB *last_tab= join->join_tab + top_level_tables; last_tab->next_select= end_send; + last_tab->cached_pfs_batch_update= last_tab->pfs_batch_update(); enum_nested_loop_state state= last_tab->aggr->end_send(); if (state >= NESTED_LOOP_OK) @@ -21348,6 +22226,7 @@ do_select(JOIN *join, Procedure *procedure) join->procedure= procedure; join->duplicate_rows= join->send_records=0; + if (join->only_const_tables() && !join->need_tmp) { Next_select_func end_select= setup_end_select_func(join, NULL); @@ -21420,6 +22299,17 @@ do_select(JOIN *join, Procedure *procedure) dbug_serve_apcs(join->thd, 1); ); + /* + We have to update the cached_pfs_batch_update as + join_tab->select_cond may have changed. + + This can happen in case of group by where some sub queries are not + needed anymore. This is checked by main.ps + */ + if (top_level_tables) + join->join_tab[top_level_tables-1].cached_pfs_batch_update= + join->join_tab[top_level_tables-1].pfs_batch_update(); + JOIN_TAB *join_tab= join->join_tab + (join->tables_list ? join->const_tables : 0); if (join->outer_ref_cond && !join->outer_ref_cond->val_int()) @@ -21811,6 +22701,8 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) { + int error; + enum_nested_loop_state rc; DBUG_ENTER("sub_select"); if (join_tab->last_inner) @@ -21830,10 +22722,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) } join_tab->tracker->r_scans++; - int error; - enum_nested_loop_state rc= NESTED_LOOP_OK; - READ_RECORD *info= &join_tab->read_record; - + rc= NESTED_LOOP_OK; for (SJ_TMP_TABLE *flush_dups_table= join_tab->flush_weedout_table; flush_dups_table; @@ -21845,9 +22734,21 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (!join_tab->preread_init_done && join_tab->preread_init()) DBUG_RETURN(NESTED_LOOP_ERROR); - join_tab->build_range_rowid_filter_if_needed(); - if (join_tab->rowid_filter && join_tab->rowid_filter->is_empty()) - rc= NESTED_LOOP_NO_MORE_ROWS; + if (unlikely(join_tab->rowid_filter)) + { + if (unlikely(join_tab->need_to_build_rowid_filter)) + { + join_tab->build_range_rowid_filter(); + /* + We have to check join_tab->rowid_filter again as the above + function may have cleared it in case of errors. + */ + if (join_tab->rowid_filter && join_tab->rowid_filter->is_empty()) + rc= NESTED_LOOP_NO_MORE_ROWS; + } + else if (join_tab->rowid_filter->is_empty()) + rc= NESTED_LOOP_NO_MORE_ROWS; + } join->return_tab= join_tab; @@ -21873,8 +22774,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (join_tab->loosescan_match_tab) join_tab->loosescan_match_tab->found_match= FALSE; - const bool pfs_batch_update= join_tab->pfs_batch_update(join); - if (pfs_batch_update) + DBUG_ASSERT(join_tab->cached_pfs_batch_update == join_tab->pfs_batch_update()); + if (join_tab->cached_pfs_batch_update) join_tab->table->file->start_psi_batch_mode(); if (rc != NESTED_LOOP_NO_MORE_ROWS) @@ -21885,11 +22786,9 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) rc= evaluate_join_record(join, join_tab, error); } - /* - Note: psergey has added the 2nd part of the following condition; the - change should probably be made in 5.1, too. - */ bool skip_over= FALSE; + READ_RECORD *info= &join_tab->read_record; + while (rc == NESTED_LOOP_OK && join->return_tab >= join_tab) { if (join_tab->loosescan_match_tab && @@ -21924,15 +22823,21 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) rc= evaluate_join_record(join, join_tab, error); } - if (rc == NESTED_LOOP_NO_MORE_ROWS && - join_tab->last_inner && !join_tab->found) - rc= evaluate_null_complemented_join_record(join, join_tab); + if (rc == NESTED_LOOP_NO_MORE_ROWS) + { + if (join_tab->last_inner && !join_tab->found) + { + rc= evaluate_null_complemented_join_record(join, join_tab); + if (rc == NESTED_LOOP_NO_MORE_ROWS) + rc= NESTED_LOOP_OK; + } + else + rc= NESTED_LOOP_OK; + } - if (pfs_batch_update) + if (join_tab->cached_pfs_batch_update) join_tab->table->file->end_psi_batch_mode(); - if (rc == NESTED_LOOP_NO_MORE_ROWS) - rc= NESTED_LOOP_OK; DBUG_RETURN(rc); } @@ -21959,7 +22864,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, ha_rows found_records=join->found_records; COND *select_cond= join_tab->select_cond; bool select_cond_result= TRUE; - DBUG_ENTER("evaluate_join_record"); DBUG_PRINT("enter", ("evaluate_join_record join: %p join_tab: %p " @@ -21987,7 +22891,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, DBUG_RETURN(NESTED_LOOP_ERROR); } - if (!select_cond || select_cond_result) + if (select_cond_result) { /* There is no select condition or the attached pushed down @@ -22303,12 +23207,16 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) if (tab->table->pos_in_table_list->is_materialized_derived() && !tab->table->pos_in_table_list->fill_me) { + DBUG_ASSERT(0); //TODO: don't get here at all - /* Skip materialized derived tables/views. */ + /* + Skip materialized derived tables/views as they temporary table is not + opened yet. + */ DBUG_RETURN(0); } - else if (tab->table->pos_in_table_list->jtbm_subselect && - tab->table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab) + else if (tab->table->pos_in_table_list->jtbm_subselect && + tab->table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab) { /* Row will not be found */ int res; @@ -22324,7 +23232,7 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) { // Info for DESCRIBE tab->info= ET_CONST_ROW_NOT_FOUND; /* Mark for EXPLAIN that the row was not found */ - pos->records_read=0.0; + pos->records_read= pos->records_out= 0.0; pos->ref_depend_map= 0; if (!table->pos_in_table_list->outer_join || error > 0) DBUG_RETURN(error); @@ -22337,20 +23245,12 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) } else { - if (/*!table->file->key_read && */ - table->covering_keys.is_set(tab->ref.key) && !table->no_keyread && - (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY) - { - table->file->ha_start_keyread(tab->ref.key); - tab->index= tab->ref.key; - } error=join_read_const(tab); - table->file->ha_end_keyread(); if (unlikely(error)) { tab->info= ET_UNIQUE_ROW_NOT_FOUND; /* Mark for EXPLAIN that the row was not found */ - pos->records_read=0.0; + pos->records_read= pos->records_out= 0.0; pos->ref_depend_map= 0; if (!table->pos_in_table_list->outer_join || error > 0) DBUG_RETURN(error); @@ -22466,10 +23366,20 @@ join_read_const(JOIN_TAB *tab) error=HA_ERR_KEY_NOT_FOUND; else { - error= table->file->ha_index_read_idx_map(table->record[0],tab->ref.key, - (uchar*) tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT); + handler *file= table->file; + if (table->covering_keys.is_set(tab->ref.key) && !table->no_keyread && + (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY) + { + file->ha_start_keyread(tab->ref.key); + /* This is probably needed for analyze table */ + tab->index= tab->ref.key; + } + error= file-> + ha_index_read_idx_map(table->record[0],tab->ref.key, + (uchar*) tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_KEY_EXACT); + file->ha_end_keyread(); } if (unlikely(error)) { @@ -22813,6 +23723,7 @@ bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab) return (join_tab->use_quick == 2 && test_if_quick_select(join_tab) > 0); } + int join_init_read_record(JOIN_TAB *tab) { bool need_unpacking= FALSE; @@ -22830,7 +23741,8 @@ int join_init_read_record(JOIN_TAB *tab) need_unpacking= tbl ? tbl->is_sjm_scan_table() : FALSE; } - tab->build_range_rowid_filter_if_needed(); + if (tab->need_to_build_rowid_filter) + tab->build_range_rowid_filter(); if (tab->filesort && tab->sort_table()) // Sort table. return 1; @@ -22862,10 +23774,29 @@ int join_init_read_record(JOIN_TAB *tab) save_copy= tab->read_record.copy_field; save_copy_end= tab->read_record.copy_field_end; - if (init_read_record(&tab->read_record, tab->join->thd, tab->table, - tab->select, tab->filesort_result, 1, 1, FALSE)) - return 1; + /* + JT_NEXT means that we should use an index scan on index 'tab->index' + However if filesort is set, the table was already sorted above + and now have to retrive the rows from the tmp file or by rnd_pos() + If !(tab->select && tab->select->quick)) it means that we are + in "Range checked for each record" and we better let the normal + init_read_record() handle this case + */ + if (tab->type == JT_NEXT && ! tab->filesort && + !(tab->select && tab->select->quick)) + { + /* Used with covered_index scan or force index */ + if (init_read_record_idx(&tab->read_record, tab->join->thd, tab->table, + 1, tab->index, 0)) + return 1; + } + else + { + if (init_read_record(&tab->read_record, tab->join->thd, tab->table, + tab->select, tab->filesort_result, 1, 1, FALSE)) + return 1; + } tab->read_record.copy_field= save_copy; tab->read_record.copy_field_end= save_copy_end; @@ -23222,11 +24153,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) List *fields= join_tab ? (join_tab-1)->fields : join->fields; DBUG_ENTER("end_send_group"); - if (!join->items3.is_null() && !join->set_group_rpa) - { - join->set_group_rpa= true; + if (!join->items3.is_null() && join->current_ref_ptrs != join->items3) join->set_items_ref_array(join->items3); - } if (!join->first_record || end_of_records || (idx=test_if_group_changed(join->group_fields)) >= 0) @@ -23748,10 +24676,10 @@ bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item) @param cond Condition to analyze @param tables Tables for which "current field values" are available + Tables for which "current field values" are available (this + includes used_table) + (may also include PSEUDO_TABLE_BITS, and may be zero) @param used_table Table that we're extracting the condition for - tables Tables for which "current field values" are available (this - includes used_table) - (may also include PSEUDO_TABLE_BITS, and may be zero) @param join_tab_idx_arg The index of the JOIN_TAB this Item is being extracted for. MAX_TABLES if there is no corresponding JOIN_TAB. @@ -24182,6 +25110,7 @@ static int test_if_order_by_key(JOIN *join, uint key_parts; bool have_pk_suffix= false; uint pk= table->s->primary_key; + ORDER::enum_order keypart_order; DBUG_ENTER("test_if_order_by_key"); if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && @@ -24194,16 +25123,23 @@ static int test_if_order_by_key(JOIN *join, for (; order ; order=order->next, const_key_parts>>=1) { Item_field *item_field= ((Item_field*) (*order->item)->real_item()); - Field *field= item_field->field; int flag; /* Skip key parts that are constants in the WHERE clause. These are already skipped in the ORDER BY by const_expression_in_where() + for top level queries. */ for (; const_key_parts & 1 ; const_key_parts>>= 1) - key_part++; - + { + if (item_field->contains(key_part->field)) + { + /* Subquery with ORDER BY, continue with next field */ + goto next_order_field; + } + key_part++; + } + /* This check was in this function historically (although I think it's better to check it outside of this function): @@ -24228,36 +25164,27 @@ static int test_if_order_by_key(JOIN *join, goto ok; } - if (key_part == key_part_end) + if (key_part == key_part_end || + !key_part->field->part_of_sortkey.is_set(idx)) { /* - There are some items left in ORDER BY that we don't + There are some items left in ORDER BY that we don't have in the key */ DBUG_RETURN(0); } - if (key_part->field != field) - { - /* - Check if there is a multiple equality that allows to infer that field - and key_part->field are equal - (see also: compute_part_of_sort_key_for_equals) - */ - if (item_field->item_equal && - item_field->item_equal->contains(key_part->field)) - field= key_part->field; - } - if (key_part->field != field || !field->part_of_sortkey.is_set(idx)) + if (!item_field->contains(key_part->field)) DBUG_RETURN(0); - const ORDER::enum_order keypart_order= - (key_part->key_part_flag & HA_REVERSE_SORT) ? - ORDER::ORDER_DESC : ORDER::ORDER_ASC; + keypart_order= ((key_part->key_part_flag & HA_REVERSE_SORT) ? + ORDER::ORDER_DESC : ORDER::ORDER_ASC); /* set flag to 1 if we can use read-next on key, else to -1 */ flag= (order->direction == keypart_order) ? 1 : -1; if (reverse && flag != reverse) DBUG_RETURN(0); reverse=flag; // Remember if reverse + +next_order_field: if (key_part < key_part_end) key_part++; } @@ -24290,31 +25217,40 @@ ok: @return MAX_KEY no suitable key found key index otherwise + + @notes + We should not use keyread_time() as in the case of disk_read_cost= 0 + all keys would be regarded equal. */ uint find_shortest_key(TABLE *table, const key_map *usable_keys) { - double min_cost= DBL_MAX; + size_t min_length= INT_MAX32; uint best= MAX_KEY; - if (!usable_keys->is_clear_all()) + uint possible_keys= usable_keys->bits_set(); + + if (possible_keys) { + if (possible_keys == 1) + return usable_keys->find_first_bit(); + for (uint nr=0; nr < table->s->keys ; nr++) { if (usable_keys->is_set(nr)) { - double cost= table->file->keyread_time(nr, 1, table->file->records()); - if (cost < min_cost) + size_t length= table->key_storage_length(nr); + if (length < min_length) { - min_cost= cost; - best=nr; + min_length= length; + best= nr; } - DBUG_ASSERT(best < MAX_KEY); } } } return best; } + /** Test if a second key is the subkey of the first one. @@ -24690,7 +25626,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) { /* - we set ref_key=MAX_KEY instead of -1, because test_if_cheaper ordering + we set ref_key=MAX_KEY instead of -1, because test_if_cheaper_ordering() assumes that "ref_key==-1" means doing full index scan. (This is not very straightforward and we got into this situation for historical reasons. Should be fixed at some point). @@ -24777,7 +25713,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, goto use_filesort; } DBUG_ASSERT(tab->select->quick); - tab->type= JT_ALL; + tab->type= JT_RANGE; tab->ref.key= -1; tab->ref.key_parts= 0; tab->use_quick= 1; @@ -24840,13 +25776,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ if (best_key < 0 || ((select_limit >= table_records) && - (tab->type == JT_ALL && + ((tab->type == JT_ALL || tab->type == JT_RANGE) && tab->join->table_count > tab->join->const_tables + 1) && - !(table->file->index_flags(best_key, 0, 1) & HA_CLUSTERED_INDEX))) + !table->is_clustering_key(best_key))) goto use_filesort; - if (select && // psergey: why doesn't this use a quick? - table->opt_range_keys.is_set(best_key) && best_key != ref_key) + if (table->opt_range_keys.is_set(best_key) && best_key != ref_key) { key_map tmp_map; tmp_map.clear_all(); // Force the creation of quick select @@ -24879,10 +25814,10 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } order_direction= best_key_direction; /* - saved_best_key_parts is actual number of used keyparts found by the - test_if_order_by_key function. It could differ from keyinfo->user_defined_key_parts, - thus we have to restore it in case of desc order as it affects - QUICK_SELECT_DESC behaviour. + saved_best_key_parts is actual number of used keyparts found by + the test_if_order_by_key function. It could differ from + keyinfo->user_defined_key_parts, thus we have to restore it in + case of desc order as it affects QUICK_SELECT_DESC behaviour. */ used_key_parts= (order_direction == -1) ? saved_best_key_parts : best_key_parts; @@ -24934,8 +25869,9 @@ check_reverse_order: select->quick= 0; // Cleanup either reset to save_quick, // or 'delete save_quick' tab->index= best_key; - tab->read_first_record= order_direction > 0 ? - join_read_first:join_read_last; + tab->read_first_record= (order_direction > 0 ? + join_read_first: + join_read_last); tab->type=JT_NEXT; // Read with index_first(), index_next() /* @@ -24944,11 +25880,7 @@ check_reverse_order: */ if (tab->rowid_filter && table->file->is_clustering_key(tab->index)) - { - tab->range_rowid_filter_info= 0; - delete tab->rowid_filter; - tab->rowid_filter= 0; - } + tab->clear_range_rowid_filter(); if (tab->pre_idx_push_select_cond) { @@ -24978,16 +25910,12 @@ check_reverse_order: method is actually used. */ DBUG_ASSERT(tab->select->quick); - tab->type=JT_ALL; + tab->type= JT_RANGE; tab->use_quick=1; tab->ref.key= -1; tab->ref.key_parts=0; // Don't use ref key. - tab->range_rowid_filter_info= 0; if (tab->rowid_filter) - { - delete tab->rowid_filter; - tab->rowid_filter= 0; - } + tab->clear_range_rowid_filter(); tab->read_first_record= join_init_read_record; if (tab->is_using_loose_index_scan()) tab->join->tmp_table_param.precomputed_group_by= TRUE; @@ -25195,6 +26123,7 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort) } else { + fsort->own_select= false; DBUG_ASSERT(tab->type == JT_REF || tab->type == JT_EQ_REF); // Update ref value if (unlikely(cp_buffer_from_ref(thd, table, &tab->ref) && @@ -26818,6 +27747,17 @@ change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, for (uint i= 0; (item= it++); i++) { Field *field; + /* + SUM_FUNC_ITEM will be replaced by the calculated value which is + stored in the temporary table. + The first part of the following test is for items that are expressions + with SUM_FUNC_ITEMS, like 'sum(a)+1'. In this case we keep the original + item, which contain an Item_ref that points to the SUM_FUNC_ITEM that + will be replaced with a pointer to the calculated value. + The second test is for window functions. Window functions contains + only pointers to Item_refs, which will be adjusted to point to the + temporary table. + */ enum Item::Type item_type= item->type(); if ((item->with_sum_func() && item_type != Item::SUM_FUNC_ITEM) || item->with_window_func()) @@ -27777,7 +28717,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tables, bool distinct_arg, JOIN_TAB *first_top_tab) { - int quick_type; + int quick_type= -1; CHARSET_INFO *cs= system_charset_info; THD *thd= join->thd; TABLE_LIST *table_list= table->pos_in_table_list; @@ -27785,12 +28725,22 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, my_bool key_read; char table_name_buffer[SAFE_NAME_LEN]; KEY *key_info= 0; - uint key_len= 0; - quick_type= -1; + uint key_len= 0, used_index= MAX_KEY; + +#ifdef NOT_YET + /* + Would be good to keep this condition up to date. + Another alternative is to remove JOIN_TAB::cond_selectivity and use + TABLE::cond_selectivity everywhere + */ + DBUG_ASSERT(cond_selectivity == table->cond_selectivity); +#endif explain_plan= eta; eta->key.clear(); eta->quick_info= NULL; + eta->cost= join_read_time; + eta->loops= join_loops; SQL_SELECT *tab_select; /* @@ -27811,6 +28761,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, // psergey-todo: data for filtering! tracker= &eta->tracker; jbuf_tracker= &eta->jbuf_tracker; + jbuf_unpack_tracker= &eta->jbuf_unpack_tracker; /* Enable the table access time tracker only for "ANALYZE stmt" */ if (thd->lex->analyze_stmt) @@ -27887,7 +28838,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, /* "type" column */ enum join_type tab_type= type; - if ((type == JT_ALL || type == JT_HASH) && + if ((type == JT_ALL || type == JT_RANGE || type == JT_HASH) && tab_select && tab_select->quick && use_quick != 2) { cur_quick= tab_select->quick; @@ -27896,9 +28847,9 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT) || (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) || (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION)) - tab_type= type == JT_ALL ? JT_INDEX_MERGE : JT_HASH_INDEX_MERGE; + tab_type= type == JT_HASH ? JT_HASH_INDEX_MERGE : JT_INDEX_MERGE; else - tab_type= type == JT_ALL ? JT_RANGE : JT_HASH_RANGE; + tab_type= type == JT_HASH ? JT_HASH_RANGE : JT_RANGE; } eta->type= tab_type; @@ -27929,11 +28880,13 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, if (tab_type == JT_NEXT) { + used_index= index; key_info= table->key_info+index; key_len= key_info->key_length; } else if (ref.key_parts) { + used_index= ref.key; key_info= get_keyinfo_by_key_no(ref.key); key_len= ref.key_length; } @@ -27983,6 +28936,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, if (tab_type == JT_HASH_NEXT) /* full index scan + hash join */ { + used_index= index; eta->hash_next_key.set(thd->mem_root, & table->key_info[index], table->key_info[index].key_length); @@ -28033,30 +28987,26 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, } else { - ha_rows examined_rows= get_examined_rows(); + double examined_rows= get_examined_rows(); eta->rows_set= true; - eta->rows= examined_rows; + eta->rows= double_to_rows(examined_rows); /* "filtered" */ float f= 0.0; if (examined_rows) { - double pushdown_cond_selectivity= cond_selectivity; - if (pushdown_cond_selectivity == 1.0) - f= (float) (100.0 * records_read / examined_rows); - else - f= (float) (100.0 * pushdown_cond_selectivity); + f= (float) (100.0 * records_out / examined_rows); + set_if_smaller(f, 100.0); } - set_if_smaller(f, 100.0); eta->filtered_set= true; eta->filtered= f; } /* Build "Extra" field and save it */ key_read= table->file->keyread_enabled(); - if ((tab_type == JT_NEXT || tab_type == JT_CONST) && - table->covering_keys.is_set(index)) + if ((tab_type == JT_NEXT || tab_type == JT_CONST) && used_index != MAX_KEY && + table->covering_keys.is_set(used_index)) key_read=1; if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT && !((QUICK_ROR_INTERSECT_SELECT*)cur_quick)->need_to_fetch_row) @@ -28404,6 +29354,7 @@ int JOIN::save_explain_data_intern(Explain_query *output, table_map used_tables=0; join->select_lex->set_explain_type(true); + xpl_sel->cost= best_read; xpl_sel->select_id= join->select_lex->select_number; xpl_sel->select_type= join->select_lex->type; xpl_sel->linkage= select_lex->get_linkage(); @@ -28442,9 +29393,9 @@ int JOIN::save_explain_data_intern(Explain_query *output, continue; } - Explain_table_access *eta= (new (output->mem_root) - Explain_table_access(output->mem_root)); + Explain_table_access(output->mem_root, + thd->lex->analyze_stmt)); if (!eta) DBUG_RETURN(1); @@ -29340,8 +30291,8 @@ void JOIN::restore_query_plan(Join_plan_state *restore_from) @param added_where An extra conjunct to the WHERE clause to reoptimize with @param join_tables The set of tables to reoptimize - @param save_to If != NULL, save here the state of the current query plan, - otherwise reuse the existing query plan structures. + @param save_to If != NULL, save here the state of the current query + plan, otherwise reuse the existing query plan structures. @notes Given a query plan that was already optimized taking into account some WHERE @@ -29358,7 +30309,8 @@ void JOIN::restore_query_plan(Join_plan_state *restore_from) @retval REOPT_NEW_PLAN there is a new plan. @retval REOPT_OLD_PLAN no new improved plan was produced, use the old one. - @retval REOPT_ERROR an irrecovarable error occurred during reoptimization. + @retval REOPT_ERROR an irrecovarable error occurred during + reoptimization. */ JOIN::enum_reopt_result @@ -29370,8 +30322,8 @@ JOIN::reoptimize(Item *added_where, table_map join_tables, size_t org_keyuse_elements; /* Re-run the REF optimizer to take into account the new conditions. */ - if (update_ref_and_keys(thd, &added_keyuse, join_tab, table_count, added_where, - ~outer_join, select_lex, &sargables)) + if (update_ref_and_keys(thd, &added_keyuse, join_tab, table_count, + added_where, ~outer_join, select_lex, &sargables)) { delete_dynamic(&added_keyuse); return REOPT_ERROR; @@ -29425,7 +30377,7 @@ JOIN::reoptimize(Item *added_where, table_map join_tables, return REOPT_ERROR; /* Re-run the join optimizer to compute a new query plan. */ - if (choose_plan(this, join_tables)) + if (choose_plan(this, join_tables, 0)) return REOPT_ERROR; return REOPT_NEW_PLAN; @@ -29467,139 +30419,131 @@ void JOIN::cache_const_exprs() /* - Get the cost of using index keynr to read #LIMIT matching rows + Get the cost of using index keynr to read #LIMIT matching rows by calling + ha_index_next() repeatedly (either with index scan, quick or 'ref') @detail - If there is a quick select, we try to use it. - - if there is a ref(const) access, we try to use it, too. - - quick and ref(const) use different cost formulas, so if both are possible - we should make a cost-based choice. + - If there is no quick select return the full cost from + cost_for_index_read() (Doing a full scan with up to 'limit' records) - rows_limit is the number of rows we would need to read when using a full - index scan. This is generally higher than the N from "LIMIT N" clause, - because there's a WHERE condition (a part of which is used to construct a - range access we are considering using here) + @param pos Result from best_access_path(). Is NULL for + single-table UPDATE/DELETE + @param table Table to be sorted + @param keynr Which index to use + @param rows_limit How many rows we want to read. + This may be different than what was in the original + LIMIT the caller has included fanouts and extra + rows needed for handling GROUP BY. + @param rows_to_scan Number of rows to scan if there is no range. + @param read_cost Full cost, including cost of WHERE. + @param read_rows Number of rows that needs to be read - @param tab JOIN_TAB with table access (is NULL for single-table - UPDATE/DELETE) - @param rows_limit See explanation above - @param read_time OUT Cost of reading using quick or ref(const) access. + @return + 0 No possible range scan, cost is for index scan + 1 Range scan should be used + For the moment we don't take selectivity of the WHERE clause into + account when calculating the number of rows we have to read + (except what we get from quick select). - @return - true There was a possible quick or ref access, its cost is in the OUT - parameters. - false No quick or ref(const) possible (and so, the caller will attempt - to use a full index scan on this index). + The cost is calculated the following way: + (The selectivity is there to take into account the increased number of + rows that we have to read to find LIMIT matching rows) */ -static bool get_range_limit_read_cost(const JOIN_TAB *tab, - const TABLE *table, - ha_rows table_records, +static bool get_range_limit_read_cost(const POSITION *pos, + const TABLE *table, uint keynr, - ha_rows rows_limit, - double *read_time) + ha_rows rows_limit_arg, + ha_rows rows_to_scan, + double *read_cost, + double *read_rows) { - bool res= false; - /* - We need to adjust the estimates if we had a quick select (or ref(const)) on - index keynr. - */ + double rows_limit= rows2double(rows_limit_arg); if (table->opt_range_keys.is_set(keynr)) { /* Start from quick select's rows and cost. These are always cheaper than full index scan/cost. */ - double best_rows= (double) table->opt_range[keynr].rows; - double best_cost= (double) table->opt_range[keynr].cost; - - /* - Check if ref(const) access was possible on this index. - */ - if (tab) - { - key_part_map map= 1; - uint kp; - /* Find how many key parts would be used by ref(const) */ - for (kp=0; kp < MAX_REF_PARTS; map=map << 1, kp++) - { - if (!(table->const_key_parts[keynr] & map)) - break; - } - - if (kp > 0) - { - ha_rows ref_rows; - /* - Two possible cases: - 1. ref(const) uses the same #key parts as range access. - 2. ref(const) uses fewer key parts, becasue there is a - range_cond(key_part+1). - */ - if (kp == table->opt_range[keynr].key_parts) - ref_rows= table->opt_range[keynr].rows; - else - ref_rows= (ha_rows) table->key_info[keynr].actual_rec_per_key(kp-1); + double best_rows, range_rows; + double range_cost= (double) table->opt_range[keynr].cost.fetch_cost(); + best_rows= range_rows= (double) table->opt_range[keynr].rows; - if (ref_rows > 0) - { - double tmp= cost_for_index_read(tab->join->thd, table, keynr, - ref_rows, - (ha_rows) tab->worst_seeks); - if (tmp < best_cost) - { - best_cost= tmp; - best_rows= (double)ref_rows; - } - } - } + if (pos) + { + /* + Take into count table selectivity as the number of accepted + rows for this table will be 'records_out'. + + For example: + key1 BETWEEN 10 AND 1000 AND key2 BETWEEN 10 AND 20 + + If we are trying to do an ORDER BY on key1, we have to take into + account that using key2 we have to examine much fewer rows. + */ + best_rows= pos->records_out; // Best rows with any key/keys + double cond_selectivity; + /* + We assign "double range_rows" from integer #rows a few lines above + so comparison with 0.0 makes sense + */ + if (range_rows > 0.0) + cond_selectivity= best_rows / range_rows; + else + cond_selectivity= 1.0; + DBUG_ASSERT(cond_selectivity <= 1.000000001); + set_if_smaller(cond_selectivity, 1.0); + + /* + We have to examine more rows in the proportion to the selectivity of the + the table + */ + rows_limit= rows_limit / cond_selectivity; } - /* - Consider an example: - - SELECT * - FROM t1 - WHERE key1 BETWEEN 10 AND 20 AND col2='foo' - ORDER BY key1 LIMIT 10 - - If we were using a full index scan on key1, we would need to read this - many rows to get 10 matches: - - 10 / selectivity(key1 BETWEEN 10 AND 20 AND col2='foo') - - This is the number we get in rows_limit. - But we intend to use range access on key1. The rows returned by quick - select will satisfy the range part of the condition, - "key1 BETWEEN 10 and 20". We will still need to filter them with - the remainder condition, (col2='foo'). - - The selectivity of the range access is (best_rows/table_records). We need - to discount it from the rows_limit: - */ - double rows_limit_for_quick= rows_limit * (best_rows / table_records); - - if (best_rows > rows_limit_for_quick) + if (best_rows > rows_limit) { /* LIMIT clause specifies that we will need to read fewer records than quick select will return. Assume that quick select's cost is - proportional to the number of records we need to return (e.g. if we + proportional to the number of records we need to return (e.g. if we only need 1/3rd of records, it will cost us 1/3rd of quick select's read time) */ - best_cost *= rows_limit_for_quick / best_rows; + range_cost*= rows_limit / best_rows; + range_rows= rows_limit; } - *read_time= best_cost; - res= true; + *read_cost= range_cost + range_rows * WHERE_COST_THD(table->in_use); + *read_rows= range_rows; + return 1; } - return res; + + /* + Calculate the number of rows we have to check if we are + doing a full index scan (as a suitable range scan was not available). + + We assume that each of the tested indexes is not correlated + with ref_key. Thus, to select first N records we have to scan + N/selectivity(ref_key) index entries. + selectivity(ref_key) = #scanned_records/#table_records = + refkey_rows_estimate/table_records. + In any case we can't select more than #table_records. + N/(refkey_rows_estimate/table_records) > table_records + <=> N > refkey_rows_estimate. + */ + ALL_READ_COST cost= cost_for_index_read(table->in_use, table, keynr, + rows_to_scan, 0); + *read_cost= (table->file->cost(&cost) + + rows_to_scan * WHERE_COST_THD(table->in_use)); + *read_rows= rows2double(rows_to_scan); + return 0; } /** - Find a cheaper access key than a given @a key + Find a cheaper access key than a given key @param tab NULL or JOIN_TAB of the accessed table @param order Linked list of ORDER BY arguments @@ -29616,7 +30560,8 @@ static bool get_range_limit_read_cost(const JOIN_TAB *tab, @param [out] new_key Key number if success, otherwise undefined @param [out] new_key_direction Return -1 (reverse) or +1 if success, otherwise undefined - @param [out] new_select_limit Return adjusted LIMIT + @param [out] new_select_limit Estimate of the number of rows we have + to read find 'select_limit' rows. @param [out] new_used_key_parts NULL by default, otherwise return number of new_key prefix columns if success or undefined if the function fails @@ -29647,25 +30592,41 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, It may be the case if ORDER/GROUP BY is used with LIMIT. */ ha_rows best_select_limit= HA_POS_ERROR; - JOIN *join= tab ? tab->join : NULL; + JOIN *join; uint nr; key_map keys; - uint best_key_parts= 0; int best_key_direction= 0; - ha_rows best_records= 0; - double read_time; + double read_time, filesort_cost; + enum sort_type filesort_type; int best_key= -1; - bool is_best_covering= FALSE; - double fanout= 1; + double fanout; ha_rows table_records= table->stat_records(); - bool group= join && join->group && order == join->group_list; - ha_rows refkey_rows_estimate= table->opt_range_condition_rows; + bool group; const bool has_limit= (select_limit_arg != HA_POS_ERROR); - THD* thd= join ? join->thd : table->in_use; - + THD *thd= table->in_use; + POSITION *position; + ha_rows rows_estimate, refkey_rows_estimate; Json_writer_object trace_wrapper(thd); Json_writer_object trace_cheaper_ordering( thd, "reconsidering_access_paths_for_index_ordering"); + + if (tab) + { + join= tab->join; + position= &join->best_positions[tab- join->join_tab]; + group=join->group && order == join->group_list; + /* Take into account that records_out can be < 1.0 in case of GROUP BY */ + rows_estimate= double_to_rows(position->records_out+0.5); + set_if_bigger(rows_estimate, 1); + refkey_rows_estimate= rows_estimate; + } + else + { + join= NULL; + position= 0; + refkey_rows_estimate= rows_estimate= table_records; + group= 0; + } trace_cheaper_ordering.add("clause", group ? "GROUP BY" : "ORDER BY"); /* @@ -29691,26 +30652,32 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, else keys= usable_keys; - if (join) + + if (join) // True if SELECT { - uint tablenr= (uint)(tab - join->join_tab); - read_time= join->best_positions[tablenr].read_time; - for (uint i= tablenr+1; i < join->table_count; i++) + uint nr= (uint) (tab - join->join_tab); + fanout= 1.0; + if (nr != join->table_count - 1) // If not last table + fanout= (join->join_record_count / position->records_out); + else { - fanout*= join->best_positions[i].records_read; // fanout is always >= 1 - // But selectivity is =< 1 : - fanout*= join->best_positions[i].cond_selectivity; + /* Only one table. Limit cannot be bigger than table_records */ + set_if_smaller(select_limit_arg, table_records); } + read_time= position->read_time; } else - read_time= table->file->scan_time(); - - trace_cheaper_ordering.add("fanout", fanout); - /* - TODO: add cost of sorting here. - */ - read_time += COST_EPS; - trace_cheaper_ordering.add("read_time", read_time); + { + /* Probably an update or delete. Assume we will do a full table scan */ + fanout= 1.0; + read_time= table->file->cost(table->file->ha_scan_and_compare_time(rows_estimate)); + set_if_smaller(select_limit_arg, table_records); + } + + filesort_cost= cost_of_filesort(table, order, rows_estimate, + select_limit_arg, &filesort_type); + read_time+= filesort_cost; + /* Calculate the selectivity of the ref_key for REF_ACCESS. For RANGE_ACCESS we use table->opt_range_condition_rows. @@ -29735,18 +30702,35 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, set_if_bigger(refkey_rows_estimate, 1); } - if (tab) - trace_cheaper_ordering.add_table_name(tab); - else - trace_cheaper_ordering.add_table_name(table); - trace_cheaper_ordering.add("rows_estimation", refkey_rows_estimate); + if (unlikely(thd->trace_started())) + { + if (tab) + trace_cheaper_ordering.add_table_name(tab); + else + trace_cheaper_ordering.add_table_name(table); + trace_cheaper_ordering. + add("rows_estimation", rows_estimate). + add("filesort_cost", filesort_cost). + add("read_cost", read_time). + add("filesort_type", filesort_names[filesort_type].str). + add("fanout", fanout); + } + + /* + Force using an index for sorting if there was no ref key + and FORCE INDEX was used. + */ + if (table->force_index && ref_key < 0) + read_time= DBL_MAX; Json_writer_array possible_keys(thd,"possible_keys"); for (nr=0; nr < table->s->keys ; nr++) { int direction; ha_rows select_limit= select_limit_arg; + ha_rows estimated_rows_to_scan; uint used_key_parts= 0; + double range_cost, range_rows; Json_writer_object possible_key(thd); possible_key.add("index", table->key_info[nr].name); @@ -29764,9 +30748,8 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, possible_key.add("can_resolve_order", true); possible_key.add("direction", direction); bool is_covering= (table->covering_keys.is_set(nr) || - (table->file->index_flags(nr, 0, 1) & - HA_CLUSTERED_INDEX)); - /* + table->is_clustering_key(nr)); + /* Don't use an index scan with ORDER BY without limit. For GROUP BY without limit always use index scan if there is a suitable index. @@ -29776,14 +30759,11 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, queries too. */ if (is_covering || - select_limit != HA_POS_ERROR || + has_limit || (ref_key < 0 && (group || table->force_index))) { double rec_per_key; - double index_scan_time; KEY *keyinfo= table->key_info+nr; - if (select_limit == HA_POS_ERROR) - select_limit= table_records; if (group) { /* @@ -29801,6 +30781,13 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, /* Take into account the selectivity of the used pk prefix */ if (used_pk_parts) { + /* + TODO: This code need to be tested with debugger + - Why set rec_per_key to 1 if we don't have primary key data + or the full key is used ? + - If used_pk_parts == 1, we don't take into account that + the first primary key part could part of the current key. + */ KEY *pkinfo=tab->table->key_info+table->s->primary_key; /* If the values of of records per key for the prefixes @@ -29832,7 +30819,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, rec_per_key/= pkinfo->actual_rec_per_key(i); } } - } + } } set_if_bigger(rec_per_key, 1); /* @@ -29856,150 +30843,76 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, and as result we'll choose an index scan when using ref/range access + filesort will be cheaper. */ - select_limit= (ha_rows) (select_limit < fanout ? - 1 : select_limit/fanout); - - /* - refkey_rows_estimate is E(#rows) produced by the table access - strategy that was picked without regard to ORDER BY ... LIMIT. - - It will be used as the source of selectivity data. - Use table->cond_selectivity as a better estimate which includes - condition selectivity too. - */ - { - // we use MIN(...), because "Using LooseScan" queries have - // cond_selectivity=1 while refkey_rows_estimate has a better - // estimate. - refkey_rows_estimate= MY_MIN(refkey_rows_estimate, - ha_rows(table_records * - table->cond_selectivity)); - } - - /* - We assume that each of the tested indexes is not correlated - with ref_key. Thus, to select first N records we have to scan - N/selectivity(ref_key) index entries. - selectivity(ref_key) = #scanned_records/#table_records = - refkey_rows_estimate/table_records. - In any case we can't select more than #table_records. - N/(refkey_rows_estimate/table_records) > table_records - <=> N > refkey_rows_estimate. - */ + select_limit= double_to_rows(select_limit/fanout); + set_if_bigger(select_limit, 1); if (select_limit > refkey_rows_estimate) - select_limit= table_records; + estimated_rows_to_scan= table_records; else - select_limit= (ha_rows) (select_limit * - (double) table_records / - refkey_rows_estimate); - possible_key.add("updated_limit", select_limit); - rec_per_key= keyinfo->actual_rec_per_key(keyinfo->user_defined_key_parts-1); - set_if_bigger(rec_per_key, 1); + estimated_rows_to_scan= (ha_rows) (select_limit * + (double) table_records / + (double) refkey_rows_estimate); + + bool range_scan= get_range_limit_read_cost(tab ? position : 0, + table, + nr, + select_limit, + estimated_rows_to_scan, + &range_cost, + &range_rows); + if (unlikely(possible_key.trace_started())) + { + possible_key + .add("rows_to_examine", range_rows) + .add("range_scan", range_scan) + .add("scan_cost", range_cost); + } + /* - Here we take into account the fact that rows are - accessed in sequences rec_per_key records in each. - Rows in such a sequence are supposed to be ordered - by rowid/primary key. When reading the data - in a sequence we'll touch not more pages than the - table file contains. - TODO. Use the formula for a disk sweep sequential access - to calculate the cost of accessing data rows for one - index entry. + We will try use the key if: + - If there is no ref key and no usable keys has yet been found and + there is either a group by or a FORCE_INDEX + - If the new cost is better than read_time */ - index_scan_time= select_limit/rec_per_key * - MY_MIN(rec_per_key, table->file->scan_time()); - double range_scan_time; - if (get_range_limit_read_cost(tab, table, table_records, nr, - select_limit, &range_scan_time)) + if (range_cost < read_time) { - possible_key.add("range_scan_time", range_scan_time); - if (range_scan_time < index_scan_time) - index_scan_time= range_scan_time; + read_time= range_cost; + possible_key.add("chosen", true); + best_key= nr; + if (saved_best_key_parts) + *saved_best_key_parts= used_key_parts; + if (new_used_key_parts) + *new_used_key_parts= keyinfo->user_defined_key_parts; + best_key_direction= direction; + best_select_limit= estimated_rows_to_scan; } - possible_key.add("index_scan_time", index_scan_time); - - if ((ref_key < 0 && (group || table->force_index || is_covering)) || - index_scan_time < read_time) + else if (unlikely(possible_key.trace_started())) { - ha_rows quick_records= table_records; - ha_rows refkey_select_limit= (ref_key >= 0 && - !is_hash_join_key_no(ref_key) && - table->covering_keys.is_set(ref_key)) ? - refkey_rows_estimate : - HA_POS_ERROR; - if (is_best_covering && !is_covering) - { - possible_key.add("chosen", false); - possible_key.add("cause", "covering index already found"); - continue; - } - - if (is_covering && refkey_select_limit < select_limit) - { - possible_key.add("chosen", false); - possible_key.add("cause", "ref estimates better"); - continue; - } - if (table->opt_range_keys.is_set(nr)) - quick_records= table->opt_range[nr].rows; - possible_key.add("records", quick_records); - if (best_key < 0 || - (select_limit <= MY_MIN(quick_records,best_records) ? - keyinfo->user_defined_key_parts < best_key_parts : - quick_records < best_records) || - (!is_best_covering && is_covering)) - { - possible_key.add("chosen", true); - best_key= nr; - best_key_parts= keyinfo->user_defined_key_parts; - if (saved_best_key_parts) - *saved_best_key_parts= used_key_parts; - best_records= quick_records; - is_best_covering= is_covering; - best_key_direction= direction; - best_select_limit= select_limit; - } - else - { - char const *cause; - possible_key.add("chosen", false); - if (is_covering) - cause= "covering index already found"; - else - { - if (select_limit <= MY_MIN(quick_records,best_records)) - cause= "keyparts greater than the current best keyparts"; - else - cause= "rows estimation greater"; - } - possible_key.add("cause", cause); - } - } - else - { - possible_key.add("usable", false); - possible_key.add("cause", "cost"); + possible_key + .add("usable", false) + .add("cause", "cost"); } } - else + else if (unlikely(possible_key.trace_started())) { possible_key.add("usable", false); if (!group && select_limit == HA_POS_ERROR) possible_key.add("cause", "order by without limit"); } } - else + else if (unlikely(possible_key.trace_started())) { if (keys.is_set(nr)) { - possible_key.add("can_resolve_order", false); - possible_key.add("cause", "order can not be resolved by key"); + possible_key. + add("can_resolve_order", false). + add("cause", "order can not be resolved by key"); } else { - possible_key.add("can_resolve_order", false); - possible_key.add("cause", "not usable index for the query"); + possible_key. + add("can_resolve_order", false). + add("cause", "not usable index for the query"); } } } @@ -30010,8 +30923,6 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, *new_key= best_key; *new_key_direction= best_key_direction; *new_select_limit= has_limit ? best_select_limit : table_records; - if (new_used_key_parts != NULL) - *new_used_key_parts= best_key_parts; DBUG_RETURN(TRUE); } @@ -30051,7 +30962,7 @@ uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select, if (select && select->quick) return select->quick->index; // index or MAX_KEY, use quick select as is else - return table->file->key_used_on_scan; // MAX_KEY or index for some engines + return table->file->key_used_on_scan; // MAX_KEY or index for some engine } if (!is_simple_order(order)) // just to cut further expensive checks @@ -30099,11 +31010,13 @@ uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select, DBUG_ASSERT(0); } else if (limit != HA_POS_ERROR) - { // check if some index scan & LIMIT is more efficient than filesort + { + // check if some index scan & LIMIT is more efficient than filesort /* - Update opt_range_condition_rows since single table UPDATE/DELETE procedures - don't call make_join_statistics() and leave this variable uninitialized. + Update opt_range_condition_rows since single table UPDATE/DELETE + procedures don't call make_join_statistics() and leave this + variable uninitialized. */ table->opt_range_condition_rows= table->stat_records(); @@ -30681,20 +31594,22 @@ bool build_notnull_conds_for_range_scans(JOIN *join, Item *cond, @brief Build not null conditions for inner nest tables of an outer join - @param join the join for whose table nest not null conditions are to be built + @param join the join for whose table nest not null conditions are to be + built @param nest_tbl the nest of the inner tables of an outer join @details - The function assumes that nest_tbl is the nest of the inner tables of an - outer join and so an ON expression for this outer join is attached to - nest_tbl. - The function selects the tables of the nest_tbl that are not inner tables of - embedded outer joins and then it calls build_notnull_conds_for_range_scans() - for nest_tbl->on_expr and the bitmap for the selected tables. This call - finds all fields belonging to the selected tables whose null-rejectedness - can be inferred from the null-rejectedness of nest_tbl->on_expr. After this - the function recursively finds all null_rejected fields for the remaining - tables from the nest of nest_tbl. + The function assumes that nest_tbl is the nest of the inner tables + of an outer join and so an ON expression for this outer join is + attached to nest_tbl. + The function selects the tables of the nest_tbl that are not inner + tables of embedded outer joins and then it calls + build_notnull_conds_for_range_scans() for nest_tbl->on_expr and + the bitmap for the selected tables. This call finds all fields + belonging to the selected tables whose null-rejectedness can be + inferred from the null-rejectedness of nest_tbl->on_expr. After + this the function recursively finds all null_rejected fields for + the remaining tables from the nest of nest_tbl. */ static @@ -30760,6 +31675,7 @@ void JOIN::init_join_cache_and_keyread() break; case JT_HASH: case JT_ALL: + case JT_RANGE: SQL_SELECT *select; select= tab->select ? tab->select : (tab->filesort ? tab->filesort->select : NULL); @@ -30784,7 +31700,8 @@ void JOIN::init_join_cache_and_keyread() /* purecov: end */ } - if (table->file->keyread_enabled()) + if (table->file->keyread_enabled() && + !table->is_clustering_key(table->file->keyread)) { /* Here we set the read_set bitmap for all covering keys @@ -30819,8 +31736,7 @@ void JOIN::init_join_cache_and_keyread() c, which is not a problem as we read all the columns from the index tuple. */ - if (!(table->file->index_flags(table->file->keyread, 0, 1) & HA_CLUSTERED_INDEX)) - table->mark_index_columns(table->file->keyread, table->read_set); + table->mark_index_columns(table->file->keyread, table->read_set); } if (tab->cache && tab->cache->init(select_options & SELECT_DESCRIBE)) revise_cache_usage(tab); @@ -31152,7 +32068,6 @@ bool JOIN::transform_all_conds_and_on_exprs_in_join_list( return false; } - /** @} (end of group Query_Optimizer) */ diff --git a/sql/sql_select.h b/sql/sql_select.h index fa4d373d556..4b64243e1c9 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -309,11 +309,7 @@ typedef struct st_join_table { Table_access_tracker *tracker; Table_access_tracker *jbuf_tracker; - /* - Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra' - column, or 0 if there is no info. - */ - uint packed_info; + Time_and_counter_tracker *jbuf_unpack_tracker; // READ_RECORD::Setup_func materialize_table; READ_RECORD::Setup_func read_first_record; @@ -326,7 +322,6 @@ typedef struct st_join_table { */ READ_RECORD::Setup_func save_read_first_record;/* to save read_first_record */ READ_RECORD::Read_func save_read_record;/* to save read_record.read_record */ - double worst_seeks; key_map const_keys; /**< Keys with constant part */ key_map checked_keys; /**< Keys checked in find_best */ key_map needed_reg; @@ -346,9 +341,22 @@ typedef struct st_join_table { */ double read_time; + /* Copy of POSITION::records_init, set by get_best_combination() */ + double records_init; + /* Copy of POSITION::records_read, set by get_best_combination() */ double records_read; - + + /* Copy of POSITION::records_out, set by get_best_combination() */ + double records_out; + + /* + Copy of POSITION::read_time, set by get_best_combination(). The cost of + accessing the table in course of the join execution. + */ + double join_read_time; + double join_loops; + /* The selectivity of the conditions that can be pushed to the table */ double cond_selectivity; @@ -357,7 +365,32 @@ typedef struct st_join_table { double partial_join_cardinality; - table_map dependent,key_dependent; + /* set by estimate_scan_time() */ + double cached_scan_and_compare_time; + double cached_forced_index_cost; + + /* + dependent is the table that must be read before the current one + Used for example with STRAIGHT_JOIN or outer joins + */ + table_map dependent; + /* + key_dependent is dependent but add those tables that are used to compare + with a key field in a simple expression. See add_key_field(). + It is only used to prune searches in best_extension_by_limited_search() + */ + table_map key_dependent; + /* + Tables that have expression in their attached condition clause that depends + on this table. + */ + table_map related_tables; + + /* + Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra' + column, or 0 if there is no info. + */ + uint packed_info; /* This is set for embedded sub queries. It contains the table map of the outer expression, like 'A' in the following expression: @@ -377,17 +410,21 @@ typedef struct st_join_table { uint index; uint status; ///< Save status for cache uint used_fields; + uint cached_covering_key; /* Set by estimate_scan_time() */ ulong used_fieldlength; ulong max_used_fieldlength; uint used_blobs; uint used_null_fields; uint used_uneven_bit_fields; - enum join_type type; + uint cached_forced_index; + enum join_type type, cached_forced_index_type; /* If first key part is used for any key in 'key_dependent' */ bool key_start_dependent; bool cached_eq_ref_table,eq_ref_table; bool shortcut_for_distinct; bool sorted; + bool cached_pfs_batch_update; + /* If it's not 0 the number stored this field indicates that the index scan has been chosen to access the table data and we expect to scan @@ -536,10 +573,11 @@ typedef struct st_join_table { Range_rowid_filter_cost_info *range_rowid_filter_info; /* Rowid filter to be used when joining this join table */ Rowid_filter *rowid_filter; - /* Becomes true just after the used range filter has been built / filled */ - bool is_rowid_filter_built; + /* True if the plan requires a rowid filter and it's not built yet */ + bool need_to_build_rowid_filter; - void build_range_rowid_filter_if_needed(); + void build_range_rowid_filter(); + void clear_range_rowid_filter(); void cleanup(); inline bool is_using_loose_index_scan() @@ -646,11 +684,11 @@ typedef struct st_join_table { { return (is_hash_join_key_no(key) ? hj_key : table->key_info+key); } - double scan_time(); - ha_rows get_examined_rows(); + void estimate_scan_time(); + double get_examined_rows(); bool preread_init(); - bool pfs_batch_update(JOIN *join); + bool pfs_batch_update(); bool is_sjm_nest() { return MY_TEST(bush_children); } @@ -933,23 +971,59 @@ public: /* The table that's put into join order */ JOIN_TAB *table; + /* number of rows that will be read from the table */ + double records_init; + /* - The "fanout": number of output rows that will be produced (after - pushed down selection condition is applied) per each row combination of - previous tables. + Number of rows left after filtering, calculated in best_access_path() + In case of use_cond_selectivity > 1 it contains rows after the used + rowid filter (if such one exists). + If use_cond_selectivity <= 1 it contains the minimum rows of any + rowid filtering or records_init if no filter exists. + */ + double records_after_filter; + + /* + Number of expected rows before applying the full WHERE clause. This + includes rowid filter and table->cond_selectivity if + use_cond_selectivity > 1. See matching_candidates_in_table(). + Should normally not be used. */ double records_read; + /* + The number of rows after applying the WHERE clause. + + Same as the "fanout": number of output rows that will be produced (after + pushed down selection condition is applied) per each row combination of + previous tables. + + In best_access_path() it is set to the minum number of accepted rows + for any possible access method or filter: + + records_out takes into account table->cond_selectivity, the WHERE clause + related to this table calculated in calculate_cond_selectivity_for_table(), + and the used rowid filter. + + After best_access_path() records_out it does not yet take into + account the part of the WHERE clause involving preceding tables. + records_out is updated in best_extension_by_limited_search() to take these + tables into account by calling table_after_join_selectivity(). + */ + double records_out; + /* The selectivity of the pushed down conditions */ double cond_selectivity; /* Cost accessing the table in course of the entire complete join execution, i.e. cost of one access method use (e.g. 'range' or 'ref' scan ) times - number the access method will be invoked. + number the access method will be invoked and checking the WHERE clause. */ double read_time; + double loops; + double prefix_record_count; /* Cost for the join prefix */ @@ -1002,13 +1076,14 @@ public: /* Type of join (EQ_REF, REF etc) */ enum join_type type; + /* Valid only after fix_semijoin_strategies_for_picked_join_order() call: if sj_strategy!=SJ_OPT_NONE, this is the number of subsequent tables that are covered by the specified semi-join strategy */ uint n_sj_tables; - + uint forced_index; // If force_index() is used /* TRUE <=> join buffering will be used. At the moment this is based on *very* imprecise guesses made in best_access_path(). @@ -1236,6 +1311,13 @@ public: bool hash_join; bool do_send_rows; table_map const_table_map; + + /* + Tables one is allowed to use in choose_plan(). Either all or + set to a mapt of the tables in the materialized semi-join nest + */ + table_map allowed_tables; + /** Bitmap of semijoin tables that the current partial plan decided to materialize and access by lookups @@ -1343,7 +1425,9 @@ public: int dbug_join_tab_array_size; #endif - /* We also maintain a stack of join optimization states in * join->positions[] */ + /* + We also maintain a stack of join optimization states in join->positions[] + */ /******* Join optimization state members end *******/ /* @@ -1552,8 +1636,6 @@ public: /* SJM nests that are executed with SJ-Materialization strategy */ List sjm_info_list; - /** TRUE <=> ref_pointer_array is set to items3. */ - bool set_group_rpa; /** Exec time only: TRUE <=> current group has been sent */ bool group_sent; /** @@ -2350,7 +2432,7 @@ inline Item * or_items(THD *thd, Item* cond, Item *item) { return (cond ? (new (thd->mem_root) Item_cond_or(thd, cond, item)) : item); } -bool choose_plan(JOIN *join, table_map join_tables); +bool choose_plan(JOIN *join, table_map join_tables, TABLE_LIST *emb_sjm_nest); void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab, table_map last_remaining_tables, bool first_alt, uint no_jbuf_before, @@ -2438,12 +2520,23 @@ bool instantiate_tmp_table(TABLE *table, KEY *keyinfo, bool open_tmp_table(TABLE *table); double prev_record_reads(const POSITION *positions, uint idx, table_map found_ref); void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List *tlist); -double get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size); -double get_tmp_table_write_cost(THD *thd, double row_count, uint row_size); void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array); bool sort_and_filter_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse, bool skip_unprefixed_keyparts); +struct TMPTABLE_COSTS +{ + double create; + double lookup; + double write; + double avg_io_cost; + double cache_hit_ratio; + double block_size; +}; + +TMPTABLE_COSTS get_tmp_table_costs(THD *thd, double row_count, uint row_size, + bool blobs_used, bool add_row_copy_cost); + struct st_cond_statistic { Item *cond; diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index d52d6071e89..10a32abe716 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -254,6 +254,8 @@ bool servers_init(bool dont_read_servers_table) DBUG_RETURN(TRUE); thd->thread_stack= (char*) &thd; thd->store_globals(); + thd->set_query_inner((char*) STRING_WITH_LEN("intern:servers_init"), + default_charset_info); /* It is safe to call servers_reload() since servers_* arrays and hashes which will be freed there are global static objects and thus are initialized diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1fd31bd4947..6ffa4da955a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -50,6 +50,7 @@ #include "authors.h" #include "contributors.h" #include "sql_partition.h" +#include "optimizer_defaults.h" #ifdef HAVE_EVENT_SCHEDULER #include "events.h" #include "event_data_objects.h" @@ -8895,6 +8896,10 @@ bool optimize_schema_tables_reads(JOIN *join) tab; tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) { + /* + The following is true for the temporary table that will hold the + final result. + */ if (!tab->table || !tab->table->pos_in_table_list) continue; @@ -8966,6 +8971,10 @@ bool get_schema_tables_result(JOIN *join, tab; tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) { + /* + The following is true for the temporary table that will hold the + final result. + */ if (!tab->table || !tab->table->pos_in_table_list) break; @@ -9196,6 +9205,49 @@ int fill_key_cache_tables(THD *thd, TABLE_LIST *tables, COND *cond) } +/* Ensure we return 'OPTIMIZER_COST_UNDEF' if cost < 0 */ + +static double fix_cost(double cost) +{ + return cost < 0 ? OPTIMIZER_COST_UNDEF : cost; +} + +static int run_fill_optimizer_costs_tables(const LEX_CSTRING *name, + const OPTIMIZER_COSTS *costs, + TABLE *table) +{ + THD *thd= table->in_use; + DBUG_ENTER("run_fill_optimizer_costs_tables"); + + restore_record(table, s->default_values); + table->field[0]->store(name->str, name->length, system_charset_info); + table->field[1]->store(fix_cost(costs->disk_read_cost*1000.0)); + table->field[2]->store(fix_cost(costs->index_block_copy_cost*1000.0)); + table->field[3]->store(fix_cost(costs->key_cmp_cost*1000.0)); + table->field[4]->store(fix_cost(costs->key_copy_cost*1000.0)); + table->field[5]->store(fix_cost(costs->key_lookup_cost*1000.0)); + table->field[6]->store(fix_cost(costs->key_next_find_cost*1000.0)); + table->field[7]->store(fix_cost(costs->disk_read_ratio)); + table->field[8]->store(fix_cost(costs->row_copy_cost*1000.0)); + table->field[9]->store(fix_cost(costs->row_lookup_cost*1000.0)); + table->field[10]->store(fix_cost(costs->row_next_find_cost*1000.0)); + table->field[11]->store(fix_cost(costs->rowid_cmp_cost*1000.0)); + table->field[12]->store(fix_cost(costs->rowid_copy_cost*1000.0)); + + DBUG_RETURN(schema_table_store_record(thd, table)); +} + + +int fill_optimizer_costs_tables(THD *thd, TABLE_LIST *tables, COND *cond) +{ + DBUG_ENTER("fill_optimizer_costs_tables"); + + int res= process_optimizer_costs(run_fill_optimizer_costs_tables, + tables->table); + DBUG_RETURN(res); +} + + namespace Show { ST_FIELD_INFO schema_fields_info[]= @@ -9824,6 +9876,25 @@ ST_FIELD_INFO keycache_fields_info[]= }; +ST_FIELD_INFO optimizer_costs_fields_info[]= +{ + Column("ENGINE", Varchar(NAME_LEN),NOT_NULL), + Column("OPTIMIZER_DISK_READ_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_INDEX_BLOCK_COPY_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_KEY_COMPARE_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_KEY_COPY_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_KEY_LOOKUP_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_KEY_NEXT_FIND_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_DISK_READ_RATIO", Decimal(906), NOT_NULL), + Column("OPTIMIZER_ROW_COPY_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_ROW_LOOKUP_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_ROW_NEXT_FIND_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_ROWID_COMPARE_COST", Decimal(906), NOT_NULL), + Column("OPTIMIZER_ROWID_COPY_COST", Decimal(906), NOT_NULL), + CEnd() +}; + + ST_FIELD_INFO show_explain_tabular_fields_info[]= { Column("id", SLonglong(3), NULLABLE, "id"), @@ -9962,6 +10033,8 @@ ST_SCHEMA_TABLE schema_tables[]= OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"OPEN_TABLES", Show::open_tables_fields_info, 0, fill_open_tables, make_old_format, 0, -1, -1, 1, 0}, + {"OPTIMIZER_COSTS", Show::optimizer_costs_fields_info, 0, + fill_optimizer_costs_tables, 0, 0, -1,-1, 0, 0}, {"OPTIMIZER_TRACE", Show::optimizer_trace_info, 0, fill_optimizer_trace_info, NULL, NULL, -1, -1, false, 0}, {"PARAMETERS", Show::parameters_fields_info, 0, diff --git a/sql/sql_sort.h b/sql/sql_sort.h index 6c9a81a32c9..88f719b3593 100644 --- a/sql/sql_sort.h +++ b/sql/sql_sort.h @@ -541,14 +541,25 @@ to be fixed later class Sort_param { public: - uint rec_length; // Length of sorted records. - uint sort_length; // Length of sorted columns. + // Length of sorted records. ALWAYS equal to sort_length + addon_length + uint rec_length; + /* + Length of what we need to sort: Sorted columns + ref_length if not + addon fields are used + */ + uint sort_length; + /* Length of the reference to the row (rowid or primary key etc */ uint ref_length; // Length of record ref. + /* Length of all addon fields. 0 if no addon fields */ uint addon_length; // Length of addon_fields - uint res_length; // Length of records in final sorted file/buffer. + /* + The length of the 'result' we are going to return to the caller for + each sort element. Also the length of data in final sorted file/buffer. + */ + uint res_length; uint max_keys_per_buffer; // Max keys / buffer. uint min_dupl_count; - ha_rows max_rows; // Select limit, or HA_POS_ERROR if unlimited. + ha_rows limit_rows; // Select limit, or HA_POS_ERROR if unlimited. ha_rows examined_rows; // Number of examined rows. TABLE *sort_form; // For quicker make_sortkey. /** @@ -579,10 +590,14 @@ public: */ tmp_buffer.set_charset(&my_charset_bin); } - void init_for_filesort(uint sortlen, TABLE *table, - ha_rows maxrows, Filesort *filesort); - void (*unpack)(TABLE *); + void init_for_filesort(TABLE *table, Filesort *filesort, + uint sortlen, ha_rows limit_rows_arg); + void setup_lengths_and_limit(TABLE *table, + uint sortlen, + uint addon_length, + ha_rows limit_rows_arg); + void (*unpack)(TABLE *); /// Enables the packing of addons if possible. void try_to_pack_addons(ulong max_length_for_sort_data); diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 40760c1e2eb..5930ebd8256 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3741,10 +3741,15 @@ void set_statistics_for_table(THD *thd, TABLE *table) { TABLE_STATISTICS_CB *stats_cb= &table->s->stats_cb; Table_statistics *read_stats= stats_cb->table_stats; - table->used_stat_records= + + /* + The MAX below is to ensure that we don't return 0 rows for a table if it + not guaranteed to be empty. + */ + table->used_stat_records= (!check_eits_preferred(thd) || !table->stats_is_read || read_stats->cardinality_is_null) ? - table->file->stats.records : read_stats->cardinality; + table->file->stats.records : MY_MAX(read_stats->cardinality, 1); /* For partitioned table, EITS statistics is based on data from all partitions. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9a60da58022..db9a67da094 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2105,7 +2105,8 @@ static int sort_keys(KEY *a, KEY *b) return -1; /* Long Unique keys should always be last unique key. - Before this patch they used to change order wrt to partial keys (MDEV-19049) + Before this patch they used to change order wrt to partial keys + (MDEV-19049) */ if (a->algorithm == HA_KEY_ALG_LONG_HASH) return 1; diff --git a/sql/sql_test.cc b/sql/sql_test.cc index b85b37b1726..6c2bbedef6d 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -383,7 +383,7 @@ void print_sjm(SJ_MATERIALIZATION_INFO *sjm) } fprintf(DBUG_FILE, " }\n"); fprintf(DBUG_FILE, " materialize_cost= %g\n", - sjm->materialization_cost.total_cost()); + sjm->materialization_cost); fprintf(DBUG_FILE, " rows= %g\n", sjm->rows); fprintf(DBUG_FILE, "}\n"); DBUG_UNLOCK_FILE; @@ -698,14 +698,15 @@ void print_keyuse_array_for_trace(THD *thd, DYNAMIC_ARRAY *keyuse_array) { keyuse_elem.add("index", keyuse->table->key_info[keyuse->key].name); } - keyuse_elem.add("field", (keyuse->keypart == FT_KEYPART) ? "": - (keyuse->is_for_hash_join() ? - keyuse->table->field[keyuse->keypart] - ->field_name.str : - keyuse->table->key_info[keyuse->key] - .key_part[keyuse->keypart] - .field->field_name.str)); - keyuse_elem.add("equals",keyuse->val); - keyuse_elem.add("null_rejecting",keyuse->null_rejecting); + keyuse_elem. + add("field", (keyuse->keypart == FT_KEYPART) ? "": + (keyuse->is_for_hash_join() ? + keyuse->table->field[keyuse->keypart] + ->field_name.str : + keyuse->table->key_info[keyuse->key] + .key_part[keyuse->keypart] + .field->field_name.str)). + add("equals",keyuse->val). + add("null_rejecting",keyuse->null_rejecting); } } diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 066d6b7483d..b4a7a0d5091 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -705,11 +705,11 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl, goto err; wrapper_sl->select_number= ++thd->lex->stmt_lex->current_select_number; wrapper_sl->parent_lex= lex; /* Used in init_query. */ - wrapper_sl->init_query(); - wrapper_sl->init_select(); + wrapper_sl->make_empty_select(); wrapper_sl->nest_level= tvc_sl->nest_level; wrapper_sl->parsing_place= tvc_sl->parsing_place; + wrapper_sl->distinct= tvc_sl->distinct; wrapper_sl->set_linkage(tvc_sl->get_linkage()); wrapper_sl->exclude_from_table_unique_test= tvc_sl->exclude_from_table_unique_test; @@ -737,6 +737,7 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl, derived_unit->init_query(); derived_unit->thd= thd; derived_unit->include_down(wrapper_sl); + derived_unit->distinct= tvc_sl->distinct; /* Attach the select used of TVC as the only slave to the unit for @@ -953,8 +954,10 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd, if (!length || length > tmp_table_max_key_length() || args[0]->cols() > tmp_table_max_key_parts()) { - trace_conv.add("done", false); - trace_conv.add("reason", "key is too long"); + if (unlikely(trace_conv.trace_started())) + trace_conv. + add("done", false). + add("reason", "key is too long"); return this; } @@ -962,15 +965,19 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd, { if (!args[i]->const_item()) { - trace_conv.add("done", false); - trace_conv.add("reason", "non-constant element in the IN-list"); + if (unlikely(trace_conv.trace_started())) + trace_conv. + add("done", false). + add("reason", "non-constant element in the IN-list"); return this; } if (cmp_row_types(args[i], args[0])) { - trace_conv.add("done", false); - trace_conv.add("reason", "type mismatch"); + if (unlikely(trace_conv.trace_started())) + trace_conv. + add("done", false). + add("reason", "type mismatch"); return this; } } @@ -1005,7 +1012,9 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd, lex->init_select(); tvc_select= lex->current_select; derived_unit= tvc_select->master_unit(); + derived_unit->distinct= 1; tvc_select->set_linkage(DERIVED_TABLE_TYPE); + tvc_select->distinct= 1; /* Create TVC used in the transformation */ if (create_value_list_for_tvc(thd, &values)) @@ -1038,7 +1047,9 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd, sq_select->add_where_field(derived_unit->first_select()); sq_select->context.table_list= sq_select->table_list.first; sq_select->context.first_name_resolution_table= sq_select->table_list.first; - sq_select->table_list.first->derived_type= DTYPE_TABLE | DTYPE_MATERIALIZE; + sq_select->table_list.first->derived_type= (DTYPE_TABLE | + DTYPE_MATERIALIZE | + DTYPE_IN_PREDICATE); lex->derived_tables|= DERIVED_SUBQUERY; sq_select->where= 0; diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 02f068e9bbc..785ba2adccc 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -181,6 +181,8 @@ void udf_init() initialized = 1; new_thd->thread_stack= (char*) &new_thd; new_thd->store_globals(); + new_thd->set_query_inner((char*) STRING_WITH_LEN("intern:udf_init"), + default_charset_info); new_thd->set_db(&MYSQL_SCHEMA_NAME); tables.init_one_table(&new_thd->db, &MYSQL_FUNC_NAME, 0, TL_READ); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 0a92422676a..e77023f1fd3 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -354,8 +354,6 @@ select_unit::create_result_table(THD *thd_arg, List *column_types, return TRUE; table->keys_in_use_for_query.clear_all(); - for (uint i=0; i < table->s->fields; i++) - table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG); if (create_table) { @@ -393,9 +391,6 @@ select_union_recursive::create_result_table(THD *thd_arg, return true; incr_table->keys_in_use_for_query.clear_all(); - for (uint i=0; i < table->s->fields; i++) - incr_table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG); - return false; } @@ -1302,6 +1297,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, bool instantiate_tmp_table= false; bool single_tvc= !first_sl->next_select() && first_sl->tvc; bool single_tvc_wo_order= single_tvc && !first_sl->order_list.elements; + bool distinct_key= 0; DBUG_ENTER("st_select_lex_unit::prepare"); DBUG_ASSERT(thd == current_thd); @@ -1405,15 +1401,17 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, { case INTERSECT_TYPE: have_intersect= TRUE; - if (!s->distinct){ - have_except_all_or_intersect_all= true; - } + if (!s->distinct) + have_except_all_or_intersect_all= TRUE; break; case EXCEPT_TYPE: have_except= TRUE; - if (!s->distinct){ + if (!s->distinct) have_except_all_or_intersect_all= TRUE; - } + break; + case DERIVED_TABLE_TYPE: + if (s->distinct) + distinct_key= 1; break; default: break; @@ -1620,7 +1618,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, if (join_union_item_types(thd, types, union_part_count + 1)) goto err; if (union_result->create_result_table(thd, &types, - MY_TEST(union_distinct), + (MY_TEST(union_distinct) || + distinct_key), create_options, &derived_arg->alias, false, instantiate_tmp_table, false, @@ -1643,7 +1642,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, res= derived_arg->derived_result->create_result_table(thd, &types, - FALSE, + distinct_key, create_options, &derived_arg->alias, FALSE, FALSE, @@ -1767,9 +1766,9 @@ cont: union_result->create_result_table(thd, &types, MY_TEST(union_distinct) || have_except_all_or_intersect_all || - have_intersect, - create_options, &empty_clex_str, false, - instantiate_tmp_table, false, + have_intersect || distinct_key, + create_options, &empty_clex_str, + false, instantiate_tmp_table, false, hidden); union_result->addon_cnt= hidden; for (uint i= 0; i < hidden; i++) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index f56ec5c83c9..4173d6d82ec 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -581,8 +581,10 @@ int mysql_update(THD *thd, set_statistics_for_table(thd, table); select= make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); - if (unlikely(error || !limit || thd->is_error() || - (select && select->check_quick(thd, safe_update, limit)))) + if (unlikely(error || thd->is_error() || !limit || + (select && select->check_quick(thd, safe_update, limit)) || + table->stat_records() == 0)) + { query_plan.set_impossible_where(); if (thd->lex->describe || thd->lex->analyze_stmt) @@ -833,15 +835,15 @@ int mysql_update(THD *thd, table->use_all_columns(); /* - We are doing a search on a key that is updated. In this case - we go trough the matching rows, save a pointer to them and - update these in a separate loop based on the pointer. + We are doing a search on a key that is updated. In this case + we go trough the matching rows, save a pointer to them and + update these in a separate loop based on the pointer. */ explain->buf_tracker.on_scan_init(); IO_CACHE tempfile; if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX, - DISK_BUFFER_SIZE, MYF(MY_WME))) - goto err; + DISK_CHUNK_SIZE, MYF(MY_WME))) + goto err; /* If quick select is used, initialize it before retrieving rows. */ if (select && select->quick && select->quick->reset()) @@ -2271,6 +2273,7 @@ static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab, case JT_REF: case JT_REF_OR_NULL: return !is_key_used(table, join_tab->ref.key, table->write_set); + case JT_RANGE: case JT_ALL: if (bitmap_is_overlapping(&table->tmp_set, table->write_set)) return FALSE; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 30fba1bcf98..89251e33f7f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -67,8 +67,8 @@ static void make_unique_view_field_name(THD *thd, Item *target, List &item_list, Item *last_element) { - const char *name= (target->orig_name ? - target->orig_name : + const char *name= (target->orig_name.str ? + target->orig_name.str : target->name.str); size_t name_len; uint attempt; @@ -100,8 +100,8 @@ static void make_unique_view_field_name(THD *thd, Item *target, itc.rewind(); } - if (!target->orig_name) - target->orig_name= target->name.str; + if (!target->orig_name.str) + target->orig_name= target->name; target->set_name(thd, buff, name_len, system_charset_info); } @@ -186,7 +186,7 @@ void make_valid_column_names(THD *thd, List &item_list) if (item->is_explicit_name() || !check_column_name(item->name.str)) continue; name_len= my_snprintf(buff, NAME_LEN, "Name_exp_%u", column_no); - item->orig_name= item->name.str; + item->orig_name= item->name; item->set_name(thd, buff, name_len, system_charset_info); } diff --git a/sql/sql_window.cc b/sql/sql_window.cc index c0acecd138f..c9f2256ff16 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -423,6 +423,16 @@ ORDER *st_select_lex::find_common_window_func_partition_fields(THD *thd) #define CMP_GT_C 1 // Greater than and compatible #define CMP_GT 2 // Greater then + +/* + This function is used for sorting ORDER/PARTITION BY clauses of window + functions and so must implement an order relation on ORDER BY clauses" + + It is called by a sorting function. + The function return's CMP_EQ (=0) if the values are identical. + If not equal, it returns a stable value < or > than 0. +*/ + static int compare_order_elements(ORDER *ord1, int weight1, ORDER *ord2, int weight2) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f0ed46646ae..0c3aaf79c6f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -8277,7 +8277,7 @@ assign_to_keycache_parts: key_cache_name: ident { $$= $1; } - | DEFAULT { $$ = default_key_cache_base; } + | DEFAULT { $$ = default_base; } ; preload: @@ -12502,13 +12502,8 @@ opt_procedure_or_into: } | into opt_select_lock_type { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_WARN_DEPRECATED_SYNTAX, - ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX), - " INTO " - " FROM...'"); $$= $2; + status_var_increment(thd->status_var.feature_into_outfile); } ; @@ -12731,6 +12726,7 @@ into_destination: new (thd->mem_root) select_export(thd, lex->exchange)))) MYSQL_YYABORT; + status_var_increment(thd->status_var.feature_into_outfile); } opt_load_data_charset { Lex->exchange->cs= $4; } @@ -12753,6 +12749,7 @@ into_destination: | select_var_list_init { Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); + status_var_increment(thd->status_var.feature_into_variable); } ; diff --git a/sql/structs.h b/sql/structs.h index b36f8e6a1a0..1da50522991 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -96,12 +96,22 @@ class engine_option_value; struct ha_index_option_struct; typedef struct st_key { - uint key_length; /* total length of user defined key parts */ - ulong flags; /* dupp key and pack flags */ + ulong flags; /* dupp key and pack flags */ + ulong ext_key_flags; /* Flags for extended key */ + ulong index_flags; /* Copy of handler->index_flags(index_number, 0, 1) */ + uint key_length; /* total length of user defined key parts */ uint user_defined_key_parts; /* How many key_parts */ uint usable_key_parts; /* Should normally be = user_defined_key_parts */ - uint ext_key_parts; /* Number of key parts in extended key */ - ulong ext_key_flags; /* Flags for extended key */ + uint ext_key_parts; /* Number of key parts in extended key */ + uint block_size; + /* + The flag is on if statistical data for the index prefixes + has to be taken from the system statistical tables. + */ + bool is_statistics_from_stat_tables; + bool without_overlaps; + bool is_ignored; // TRUE if index needs to be ignored + /* Parts of primary key that are in the extension of this index. @@ -123,13 +133,7 @@ typedef struct st_key { /* Set of keys constraint correlated with this key */ key_map constraint_correlated; LEX_CSTRING name; - uint block_size; enum ha_key_alg algorithm; - /* - The flag is on if statistical data for the index prefixes - has to be taken from the system statistical tables. - */ - bool is_statistics_from_stat_tables; /* Note that parser is used when the table is opened for use, and parser_name is used when the table is being created. @@ -167,12 +171,6 @@ typedef struct st_key { ha_index_option_struct *option_struct; /* structure with parsed options */ double actual_rec_per_key(uint i); - - bool without_overlaps; - /* - TRUE if index needs to be ignored - */ - bool is_ignored; } KEY; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index c508f73fe25..28443c8f4f7 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -53,8 +53,9 @@ #include "debug_sync.h" // DEBUG_SYNC #include "sql_show.h" #include "opt_trace_context.h" - #include "log_event.h" +#include "optimizer_defaults.h" + #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE #include "../storage/perfschema/pfs_server.h" #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ @@ -6680,7 +6681,7 @@ static Sys_var_enum Sys_histogram_type( "DOUBLE_PREC_HB - double precision height-balanced, " "JSON_HB - height-balanced, stored as JSON.", SESSION_VAR(histogram_type), CMD_LINE(REQUIRED_ARG), - histogram_types, DEFAULT(1)); + histogram_types, DEFAULT(2)); static Sys_var_mybool Sys_no_thread_alarm( "debug_no_thread_alarm", @@ -6946,20 +6947,6 @@ static Sys_var_mybool Sys_session_track_user_variables( #endif //EMBEDDED_LIBRARY -static Sys_var_uint Sys_in_subquery_conversion_threshold( - "in_predicate_conversion_threshold", - "The minimum number of scalar elements in the value list of " - "IN predicate that triggers its conversion to IN subquery. Set to " - "0 to disable the conversion.", - SESSION_VAR(in_subquery_conversion_threshold), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, UINT_MAX), DEFAULT(IN_SUBQUERY_CONVERSION_THRESHOLD), BLOCK_SIZE(1)); - -static Sys_var_ulong Sys_optimizer_max_sel_arg_weight( - "optimizer_max_sel_arg_weight", - "The maximum weight of the SEL_ARG graph. Set to 0 for no limit", - SESSION_VAR(optimizer_max_sel_arg_weight), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, ULONG_MAX), DEFAULT(SEL_ARG::MAX_WEIGHT), BLOCK_SIZE(1)); - static Sys_var_enum Sys_secure_timestamp( "secure_timestamp", "Restricts direct setting of a session " "timestamp. Possible levels are: YES - timestamp cannot deviate from " @@ -6984,3 +6971,129 @@ static Sys_var_bit Sys_system_versioning_insert_history( SESSION_VAR(option_bits), CMD_LINE(OPT_ARG), OPTION_INSERT_HISTORY, DEFAULT(FALSE), NO_MUTEX_GUARD, IN_BINLOG); + +/* Optimizer variables */ + +static Sys_var_uint Sys_in_subquery_conversion_threshold( + "in_predicate_conversion_threshold", + "The minimum number of scalar elements in the value list of " + "IN predicate that triggers its conversion to IN subquery. Set to " + "0 to disable the conversion.", + SESSION_VAR(in_subquery_conversion_threshold), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, UINT_MAX), DEFAULT(IN_SUBQUERY_CONVERSION_THRESHOLD), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_optimizer_max_sel_arg_weight( + "optimizer_max_sel_arg_weight", + "The maximum weight of the SEL_ARG graph. Set to 0 for no limit", + SESSION_VAR(optimizer_max_sel_arg_weight), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, ULONG_MAX), DEFAULT(SEL_ARG::MAX_WEIGHT), BLOCK_SIZE(1)); + + +static Sys_var_engine_optimizer_cost Sys_optimizer_disk_read_ratio( + "optimizer_disk_read_ratio", + "Chance that we have to do a disk read to find a row or index entry from " + "the engine cache (cache_misses/total_cache_requests). 0.0 means that " + "everything is cached and 1.0 means that nothing is expected to be in the " + "engine cache.", + COST_VAR(disk_read_ratio), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_DISK_READ_RATIO), + VALID_RANGE(0.0, 1.0), DEFAULT(DEFAULT_DISK_READ_RATIO), COST_ADJUST(1)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_key_lookup_cost( + "optimizer_key_lookup_cost", + "Cost for finding a key based on a key value", + COST_VAR(key_lookup_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_KEY_LOOKUP_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_KEY_LOOKUP_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_row_lookup_cost( + "optimizer_row_lookup_cost", + "Cost of finding a row based on a rowid or a clustered key.", + COST_VAR(row_lookup_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_ROW_LOOKUP_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_ROW_LOOKUP_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_disk_read_cost( + "optimizer_disk_read_cost", + "Cost of reading a block of IO_SIZE (4096) from a disk (in usec).", + COST_VAR(disk_read_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_DISK_READ_COST), + VALID_RANGE(0, 10000), DEFAULT(DEFAULT_DISK_READ_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_key_copy_cost( + "optimizer_key_copy_cost", + "Cost of finding the next key in the engine and copying it to the SQL " + "layer.", + COST_VAR(key_copy_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_KEY_COPY_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_KEY_COPY_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_index_block_copy_cost( + "optimizer_index_block_copy_cost", + "Cost of copying a key block from the cache to intern storage as part of " + "an index scan.", + COST_VAR(index_block_copy_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_INDEX_BLOCK_COPY_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_INDEX_BLOCK_COPY_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_row_next_find_cost( + "optimizer_row_next_find_cost", + "Cost of finding the next row when scanning the table.", + COST_VAR(row_next_find_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_ROW_NEXT_FIND_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_ROW_NEXT_FIND_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_key_next_find_cost( + "optimizer_key_next_find_cost", + "Cost of finding the next key and rowid when using filters.", + COST_VAR(key_next_find_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_KEY_NEXT_FIND_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_KEY_NEXT_FIND_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_row_copy_cost( + "optimizer_row_copy_cost", + "Cost of copying a row from the engine or the join cache to the SQL layer.", + COST_VAR(row_copy_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_ROW_COPY_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_ROW_COPY_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_key_cmp_cost( + "optimizer_key_compare_cost", + "Cost of checking a key against the end key condition.", + COST_VAR(key_cmp_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_KEY_CMP_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_KEY_COMPARE_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_rowid_cmp_cost( + "optimizer_rowid_compare_cost", + "Cost of comparing two rowid's", + COST_VAR(rowid_cmp_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_ROWID_CMP_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_ROWID_COMPARE_COST), COST_ADJUST(1000)); + +static Sys_var_engine_optimizer_cost Sys_optimizer_rowid_copy_cost( + "optimizer_rowid_copy_cost", + "Cost of copying a rowid", + COST_VAR(rowid_copy_cost), + CMD_LINE(REQUIRED_ARG, OPT_COSTS_ROWID_COPY_COST), + VALID_RANGE(0, 1000), DEFAULT(DEFAULT_ROWID_COPY_COST), COST_ADJUST(1000)); + +/* The following costs are stored in THD and handler */ + +static Sys_var_optimizer_cost Sys_optimizer_where_cost( + "optimizer_where_cost", + "Cost of checking the row against the WHERE clause. Increasing this will " + "have the optimizer to prefer plans with less row combinations.", + SESSION_VAR(optimizer_where_cost), + CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 100000), DEFAULT(DEFAULT_WHERE_COST), COST_ADJUST(1000)); + +static Sys_var_optimizer_cost Sys_optimizer_scan_cost( + "optimizer_scan_setup_cost", + "Extra cost added to TABLE and INDEX scans to get optimizer to prefer " + "index lookups.", + SESSION_VAR(optimizer_scan_setup_cost), + CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 100000000), DEFAULT(DEFAULT_TABLE_SCAN_SETUP_COST), + COST_ADJUST(1000)); diff --git a/sql/sys_vars.inl b/sql/sys_vars.inl index b1d7bc31255..2c5acdcdc6b 100644 --- a/sql/sys_vars.inl +++ b/sql/sys_vars.inl @@ -32,6 +32,7 @@ #include "rpl_mi.h" // For Multi-Source Replication #include "debug_sync.h" #include "sql_acl.h" // check_global_access() +#include "optimizer_defaults.h" // create_optimizer_costs /* a set of mostly trivial (as in f(X)=X) defines below to make system variable @@ -40,6 +41,7 @@ #define VALID_RANGE(X,Y) X,Y #define DEFAULT(X) X #define BLOCK_SIZE(X) X +#define COST_ADJUST(X) X #define GLOBAL_VAR(X) sys_var::GLOBAL, (((char*)&(X))-(char*)&global_system_variables), sizeof(X) #define SESSION_VAR(X) sys_var::SESSION, offsetof(SV, X), sizeof(((SV *)0)->X) #define SESSION_ONLY(X) sys_var::ONLY_SESSION, offsetof(SV, X), sizeof(((SV *)0)->X) @@ -1048,7 +1050,7 @@ public: /* If no basename, assume it's for the key cache named 'default' */ if (!base_name->length) - base_name= &default_key_cache_base; + base_name= &default_base; key_cache= get_key_cache(base_name); @@ -1198,7 +1200,6 @@ public: option.var_type|= GET_DOUBLE; option.min_value= (longlong) getopt_double2ulonglong(min_val); option.max_value= (longlong) getopt_double2ulonglong(max_val); - global_var(double)= (double)option.def_value; SYSVAR_ASSERT(min_val < max_val); SYSVAR_ASSERT(min_val <= def_val); SYSVAR_ASSERT(max_val >= def_val); @@ -1228,6 +1229,139 @@ public: { var->save_result.double_value= getopt_ulonglong2double(option.def_value); } }; + +/* + Optimizer costs + Stored as cost factor (1 cost = 1 ms). + Given and displayed as microsconds (as most values are very small) +*/ + +class Sys_var_optimizer_cost: public Sys_var_double +{ +public: + double cost_adjust; + Sys_var_optimizer_cost(const char *name_arg, + const char *comment, int flag_args, ptrdiff_t off, size_t size, + CMD_LINE getopt, + double min_val, double max_val, double def_val, + ulong arg_cost_adjust, PolyLock *lock=0, + enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, + on_check_function on_check_func=0, + on_update_function on_update_func=0, + const char *substitute=0) + :Sys_var_double(name_arg, comment, flag_args, off, size, getopt, + min_val, max_val, def_val * arg_cost_adjust, lock, + binlog_status_arg, + on_check_func, + on_update_func, + substitute) + { + cost_adjust= (double) arg_cost_adjust; + } + bool session_update(THD *thd, set_var *var) + { + session_var(thd, double)= var->save_result.double_value/cost_adjust; + return false; + } + bool global_update(THD *thd, set_var *var) + { + global_var(double)= var->save_result.double_value/cost_adjust; + return false; + } + void session_save_default(THD *thd, set_var *var) + { var->save_result.double_value= global_var(double) * cost_adjust; } + + void global_save_default(THD *thd, set_var *var) + { + var->save_result.double_value= getopt_ulonglong2double(option.def_value); + } + const uchar *tmp_ptr(THD *thd) const + { + if (thd->sys_var_tmp.double_value > 0) + thd->sys_var_tmp.double_value*= cost_adjust; + return (uchar*) &thd->sys_var_tmp.double_value; + } + const uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base) const + { + thd->sys_var_tmp.double_value= session_var(thd, double); + return tmp_ptr(thd); + } + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const + { + thd->sys_var_tmp.double_value= global_var(double); + return tmp_ptr(thd); + } +}; + + +/* + The class for optimizer costs with structured names, unique for each engine. + Used as 'engine.variable_name' + + Class specific constructor arguments: + everything derived from Sys_var_optimizer_cost + + Backing store: double + + @note these variables can be only GLOBAL +*/ + +#define COST_VAR(X) GLOBAL_VAR(default_optimizer_costs.X) +#define cost_var_ptr(KC, OFF) (((uchar*)(KC))+(OFF)) +#define cost_var(KC, OFF) (*(double*)cost_var_ptr(KC, OFF)) + +class Sys_var_engine_optimizer_cost: public Sys_var_optimizer_cost +{ + public: + Sys_var_engine_optimizer_cost(const char *name_arg, + const char *comment, int flag_args, ptrdiff_t off, size_t size, + CMD_LINE getopt, + double min_val, double max_val, double def_val, + long cost_adjust, PolyLock *lock= 0, + const char *substitute=0) + : Sys_var_optimizer_cost(name_arg, comment, flag_args, off, size, + getopt, min_val, max_val, def_val, cost_adjust, + lock, VARIABLE_NOT_IN_BINLOG, 0, + 0, substitute) + { + option.var_type|= GET_ASK_ADDR; + option.value= (uchar**)1; // crash me, please + // fix an offset from global_system_variables to be an offset in OPTIMIZER_COSTS + offset= global_var_ptr() - (uchar*) &default_optimizer_costs; + SYSVAR_ASSERT(scope() == GLOBAL); + } + bool global_update(THD *thd, set_var *var) + { + double new_value= var->save_result.double_value; + LEX_CSTRING *base_name= &var->base; + OPTIMIZER_COSTS *optimizer_costs; + + /* If no basename, assume it's for the default costs */ + if (!base_name->length) + base_name= &default_base; + + mysql_mutex_lock(&LOCK_optimizer_costs); + if (!(optimizer_costs= get_or_create_optimizer_costs(base_name->str, + base_name->length))) + { + mysql_mutex_unlock(&LOCK_optimizer_costs); + return true; + } + cost_var(optimizer_costs, offset)= new_value / cost_adjust; + mysql_mutex_unlock(&LOCK_optimizer_costs); + return 0; + } + const uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base) const + { + OPTIMIZER_COSTS *optimizer_costs= get_optimizer_costs(base); + if (!optimizer_costs) + optimizer_costs= &default_optimizer_costs; + thd->sys_var_tmp.double_value= cost_var(optimizer_costs, offset); + return tmp_ptr(thd); + } +}; + + /** The class for the @max_user_connections. It's derived from Sys_var_uint, but non-standard session value diff --git a/sql/table.cc b/sql/table.cc index 6200288d930..3fffb974f0c 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -751,10 +751,10 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, LEX_STRING *keynames) { uint i, j, n_length; + uint primary_key_parts= 0; KEY_PART_INFO *key_part= NULL; ulong *rec_per_key= NULL; - KEY_PART_INFO *first_key_part= NULL; - uint first_key_parts= 0; + DBUG_ASSERT(keyinfo == first_keyinfo); if (!keys) { @@ -763,15 +763,15 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, bzero((char*) keyinfo, len); key_part= reinterpret_cast (keyinfo); } + bzero((char*)first_keyinfo, sizeof(*first_keyinfo)); /* - If share->use_ext_keys is set to TRUE we assume that any key - can be extended by the components of the primary key whose - definition is read first from the frm file. - For each key only those fields of the assumed primary key are - added that are not included in the proper key definition. - If after all it turns out that there is no primary key the - added components are removed from each key. + If share->use_ext_keys is set to TRUE we assume that any not + primary key, can be extended by the components of the primary key + whose definition is read first from the frm file. + This code only allocates space for the extend key information as + we at this point don't know if there is a primary key or not. + The extend key information is added in init_from_binary_frm_image(). When in the future we support others schemes of extending of secondary keys with components of the primary key we'll have @@ -804,26 +804,31 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, if (i == 0) { - (*ext_key_parts)+= (share->use_ext_keys ? first_keyinfo->user_defined_key_parts*(keys-1) : 0); + /* + Allocate space for keys. We have to do it there as we need to know + the number of used_defined_key_parts for the first key when doing + this. + */ + primary_key_parts= first_keyinfo->user_defined_key_parts; + (*ext_key_parts)+= (share->use_ext_keys ? + primary_key_parts*(keys-1) : + 0); n_length=keys * sizeof(KEY) + *ext_key_parts * sizeof(KEY_PART_INFO); if (!(keyinfo= (KEY*) alloc_root(&share->mem_root, n_length + len))) return 1; - bzero((char*) keyinfo,n_length); share->key_info= keyinfo; + + /* Copy first keyinfo, read above */ + memcpy((char*) keyinfo, (char*) first_keyinfo, sizeof(*keyinfo)); + bzero(((char*) keyinfo) + sizeof(*keyinfo), n_length - sizeof(*keyinfo)); + key_part= reinterpret_cast (keyinfo + keys); if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root, sizeof(ulong) * *ext_key_parts))) return 1; - first_key_part= key_part; - first_key_parts= first_keyinfo->user_defined_key_parts; - keyinfo->flags= first_keyinfo->flags; - keyinfo->key_length= first_keyinfo->key_length; - keyinfo->user_defined_key_parts= first_keyinfo->user_defined_key_parts; - keyinfo->algorithm= first_keyinfo->algorithm; - if (new_frm_ver >= 3) - keyinfo->block_size= first_keyinfo->block_size; + bzero((char*) rec_per_key, sizeof(*rec_per_key) * *ext_key_parts); } keyinfo->key_part= key_part; @@ -833,7 +838,7 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, if (strpos + (new_frm_ver >= 1 ? 9 : 7) >= frm_image_end) return 1; if (!(keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)) - *rec_per_key++=0; + rec_per_key++; key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK); key_part->offset= (uint) uint2korr(strpos+2)-1; key_part->key_type= (uint) uint2korr(strpos+5); @@ -857,48 +862,33 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, } key_part->store_length=key_part->length; } - if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH) - { - keyinfo->key_length= HA_HASH_KEY_LENGTH_WITHOUT_NULL; - key_part++; // reserved for the hash value - *rec_per_key++=0; - } - /* - Add primary key to end of extended keys for non unique keys for - storage engines that supports it. - */ keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; keyinfo->ext_key_flags= keyinfo->flags; keyinfo->ext_key_part_map= 0; - if (share->use_ext_keys && i && !(keyinfo->flags & HA_NOSAME)) - { - for (j= 0; - j < first_key_parts && keyinfo->ext_key_parts < MAX_REF_PARTS; - j++) - { - uint key_parts= keyinfo->user_defined_key_parts; - KEY_PART_INFO* curr_key_part= keyinfo->key_part; - KEY_PART_INFO* curr_key_part_end= curr_key_part+key_parts; - for ( ; curr_key_part < curr_key_part_end; curr_key_part++) - { - if (curr_key_part->fieldnr == first_key_part[j].fieldnr) - break; - } - if (curr_key_part == curr_key_part_end) - { - *key_part++= first_key_part[j]; - *rec_per_key++= 0; - keyinfo->ext_key_parts++; - keyinfo->ext_key_part_map|= 1 << j; - } - } - if (j == first_key_parts) - keyinfo->ext_key_flags= keyinfo->flags | HA_EXT_NOSAME; - } + if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH) + { + /* + We should not increase keyinfo->ext_key_parts here as it will + later be changed to 1 as the engine will only see the generated hash + key. + */ + keyinfo->key_length= HA_HASH_KEY_LENGTH_WITHOUT_NULL; + key_part++; // This will be set to point to the hash key + rec_per_key++; // Only one rec_per_key needed for the hash share->ext_key_parts++; + } + + if (i && share->use_ext_keys && !((keyinfo->flags & HA_NOSAME))) + { + /* Reserve place for extended key parts */ + key_part+= primary_key_parts; + rec_per_key+= primary_key_parts; + share->ext_key_parts+= primary_key_parts; // For copy_keys_from_share() + } share->ext_key_parts+= keyinfo->ext_key_parts; + DBUG_ASSERT(share->ext_key_parts <= *ext_key_parts); } keynames->str= (char*) key_part; keynames->length= strnmov(keynames->str, (char *) strpos, @@ -1292,10 +1282,10 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, for (key_index= 0; key_index < table->s->keys; key_index++) { key=table->key_info + key_index; - parts= key->user_defined_key_parts; + parts= key->user_defined_key_parts; if (key->key_part[parts].fieldnr == field->field_index + 1) break; - } + } if (!key || key->algorithm != HA_KEY_ALG_LONG_HASH) goto end; KEY_PART_INFO *keypart; @@ -1323,7 +1313,13 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, field->vcol_info->set_vcol_type(VCOL_USING_HASH); if (v->fix_and_check_expr(thd, table)) goto end; - key->user_defined_key_parts= key->ext_key_parts= key->usable_key_parts= 1; + /* + The hash key used by unique consist of one key_part. + It is stored in key_parts after the used defined parts. + The engine will only see the hash. + */ + key->user_defined_key_parts= key->usable_key_parts= + key->ext_key_parts= 1; key->key_part+= parts; if (key->flags & HA_NULL_PART_KEY) @@ -2046,7 +2042,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, next_chunk+= str_db_type_length + 2; } - share->set_use_ext_keys_flag(plugin_hton(se_plugin)->flags & HTON_SUPPORTS_EXTENDED_KEYS); + /* + Check if engine supports extended keys. This is used by + create_key_infos() to allocate room for extended keys + */ + share->set_use_ext_keys_flag(plugin_hton(se_plugin)->flags & + HTON_SUPPORTS_EXTENDED_KEYS); if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo, new_frm_ver, &ext_key_parts, @@ -2294,7 +2295,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->keynames.count != keys)) goto err; - /* Allocate handler */ + /* Allocate handler */ if (!(handler_file= get_new_handler(share, thd->mem_root, plugin_hton(se_plugin)))) goto err; @@ -2792,6 +2793,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, DBUG_ASSERT((null_pos + (null_bit_pos + 7) / 8) <= share->field[0]->ptr); } + share->primary_key= MAX_KEY; + /* Fix key->name and key_part->field */ if (key_parts) { @@ -2812,7 +2815,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, hash_keypart->type= HA_KEYTYPE_ULONGLONG; hash_keypart->key_part_flag= 0; hash_keypart->key_type= 32834; - /* Last n fields are unique_index_hash fields*/ + /* Last n fields are unique_index_hash fields */ hash_keypart->offset= offset; hash_keypart->fieldnr= hash_field_used_no + 1; hash_field= share->field[hash_field_used_no]; @@ -2826,7 +2829,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, offset+= HA_HASH_FIELD_LENGTH; } } - uint add_first_key_parts= 0; longlong ha_option= handler_file->ha_table_flags(); keyinfo= share->key_info; uint primary_key= my_strcasecmp(system_charset_info, @@ -2896,33 +2898,85 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, goto err; } + uint add_first_key_parts= 0; if (share->use_ext_keys) { if (primary_key >= MAX_KEY) - { - add_first_key_parts= 0; - share->set_use_ext_keys_flag(FALSE); - } + share->set_use_ext_keys_flag(false); else { - add_first_key_parts= first_keyinfo.user_defined_key_parts; - /* - Do not add components of the primary key starting from - the major component defined over the beginning of a field. - */ - for (i= 0; i < first_keyinfo.user_defined_key_parts; i++) - { + /* Add primary key to end of all non unique keys */ + + KEY *curr_keyinfo= keyinfo, *keyinfo_end= keyinfo+ keys; + KEY_PART_INFO *first_key_part= keyinfo->key_part; + uint first_key_parts= keyinfo->user_defined_key_parts; + + /* + We are skipping the first key (primary key) as it cannot be + extended + */ + while (++curr_keyinfo < keyinfo_end) + { + uint j; + if (!(curr_keyinfo->flags & HA_NOSAME)) + { + KEY_PART_INFO *key_part= (curr_keyinfo->key_part + + curr_keyinfo->user_defined_key_parts); + + /* Extend key with primary key parts */ + for (j= 0; + j < first_key_parts && + curr_keyinfo->ext_key_parts < MAX_REF_PARTS; + j++) + { + uint key_parts= curr_keyinfo->user_defined_key_parts; + KEY_PART_INFO *curr_key_part= curr_keyinfo->key_part; + KEY_PART_INFO *curr_key_part_end= curr_key_part+key_parts; + + for ( ; curr_key_part < curr_key_part_end; curr_key_part++) + { + if (curr_key_part->fieldnr == first_key_part[j].fieldnr) + break; + } + if (curr_key_part == curr_key_part_end) + { + /* Add primary key part not part of the current index */ + *key_part++= first_key_part[j]; + curr_keyinfo->ext_key_parts++; + curr_keyinfo->ext_key_part_map|= 1 << j; + } + } + if (j == first_key_parts) + { + /* Full primary key added to secondary keys makes it unique */ + curr_keyinfo->ext_key_flags= curr_keyinfo->flags | HA_EXT_NOSAME; + } + } + } + add_first_key_parts= keyinfo->user_defined_key_parts; + + /* + If a primary key part is using a partial key, don't use it or any key part after + it. + */ + for (i= 0; i < first_key_parts; i++) + { uint fieldnr= keyinfo[0].key_part[i].fieldnr; if (share->field[fieldnr-1]->key_length() != keyinfo[0].key_part[i].length) - { + { add_first_key_parts= i; break; } } - } + } } + /* Primary key must be set early as engine may use it in index_flag() */ + share->primary_key= (primary_key < MAX_KEY && + share->keys_in_use.is_set(primary_key) ? + primary_key : MAX_KEY); + key_first_info= keyinfo; for (uint key=0 ; key < keys ; key++,keyinfo++) { @@ -3076,12 +3130,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY) { share->keys_for_keyread.set_bit(key); + /* + part_of_key is used to check if we can use the field + as part of covering key (which implies HA_KEYREAD_ONLY). + */ field->part_of_key.set_bit(key); - if (i < keyinfo->user_defined_key_parts) - field->part_of_key_not_clustered.set_bit(key); } if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER) field->part_of_sortkey.set_bit(key); + + if (i < keyinfo->user_defined_key_parts) + field->part_of_key_not_clustered.set_bit(key); } if (!(key_part->key_part_flag & HA_REVERSE_SORT) && usable_parts == i) @@ -3165,7 +3224,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (primary_key < MAX_KEY && (share->keys_in_use.is_set(primary_key))) { - share->primary_key= primary_key; + DBUG_ASSERT(share->primary_key == primary_key); /* If we are using an integer as the primary key then allow the user to refer to it as '_rowid' @@ -3182,10 +3241,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } } else - share->primary_key = MAX_KEY; // we do not have a primary key + { + DBUG_ASSERT(share->primary_key == MAX_KEY); + } } - else - share->primary_key= MAX_KEY; if (new_field_pack_flag <= 1) { /* Old file format with default as not null */ @@ -3413,6 +3472,27 @@ err: } +/* + Make a copy of optimizer costs to be able to access these without any locks + and to allow the engine to update costs. +*/ + +void TABLE_SHARE::update_optimizer_costs(handlerton *hton) +{ + if (hton != view_pseudo_hton && !(hton->flags & HTON_HIDDEN)) + { + mysql_mutex_lock(&LOCK_optimizer_costs); + memcpy(&optimizer_costs, hton->optimizer_costs, sizeof(optimizer_costs)); + mysql_mutex_unlock(&LOCK_optimizer_costs); + } + else + { + bzero(&optimizer_costs, sizeof(optimizer_costs)); + MEM_UNDEFINED(&optimizer_costs, sizeof(optimizer_costs)); + } +} + + static bool sql_unusable_for_discovery(THD *thd, handlerton *engine, const char *sql) { @@ -4021,6 +4101,11 @@ static void print_long_unique_table(TABLE *table) } #endif + +/** + Copy key information from TABLE_SHARE to TABLE +*/ + bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root) { TABLE_SHARE *share= outparam->s; @@ -4030,14 +4115,16 @@ bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root) KEY_PART_INFO *key_part; if (!multi_alloc_root(root, &key_info, share->keys*sizeof(KEY), - &key_part, share->ext_key_parts*sizeof(KEY_PART_INFO), + &key_part, + share->ext_key_parts*sizeof(KEY_PART_INFO), NullS)) return 1; outparam->key_info= key_info; memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys); - memcpy(key_part, key_info->key_part, sizeof(*key_part)*share->ext_key_parts); + memcpy(key_part, key_info->key_part, + sizeof(*key_part)*share->ext_key_parts); my_ptrdiff_t adjust_ptrs= PTR_BYTE_DIFF(key_part, key_info->key_part); for (key_info_end= key_info + share->keys ; @@ -4048,22 +4135,44 @@ bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root) key_info->key_part= reinterpret_cast (reinterpret_cast(key_info->key_part) + adjust_ptrs); if (key_info->algorithm == HA_KEY_ALG_LONG_HASH) + { + /* + From the user point of view, this key is unique. + However from the engine point, the value is not unique + as there can be hash collisions. + */ key_info->flags&= ~HA_NOSAME; + } } + + /* + We have to copy key parts separately as LONG HASH has invisible + key parts not seen by key_info + */ for (KEY_PART_INFO *key_part_end= key_part+share->ext_key_parts; key_part < key_part_end; key_part++) { - Field *field= key_part->field= outparam->field[key_part->fieldnr - 1]; - if (field->key_length() != key_part->length && - !(field->flags & BLOB_FLAG)) + /* + key_part->field is not set for key_parts that are here not used. + This can happen with extended keys where a secondary key + contains a primary key. In this case no key_info will contain + this key_part, but it can still be part of the memory region of + share->key_part. + */ + if (key_part->field) { - /* - We are using only a prefix of the column as a key: - Create a new field for the key part that matches the index - */ - field= key_part->field=field->make_new_field(root, outparam, 0); - field->field_length= key_part->length; + Field *field= key_part->field= outparam->field[key_part->fieldnr - 1]; + if (field->key_length() != key_part->length && + !(field->flags & BLOB_FLAG)) + { + /* + We are using only a prefix of the column as a key: + Create a new field for the key part that matches the index + */ + field= key_part->field=field->make_new_field(root, outparam, 0); + field->field_length= key_part->length; + } } } } @@ -4305,15 +4414,15 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, for (uint k= 0; k < share->keys; k++) { - KEY &key_info= outparam->key_info[k]; - uint parts = (share->use_ext_keys ? key_info.ext_key_parts : - key_info.user_defined_key_parts); - for (uint p= 0; p < parts; p++) + KEY *key_info= &outparam->key_info[k]; + uint parts= (share->use_ext_keys ? key_info->ext_key_parts : + key_info->user_defined_key_parts); + for (uint p=0; p < parts; p++) { - KEY_PART_INFO &kp= key_info.key_part[p]; - if (kp.field != outparam->field[kp.fieldnr - 1]) + KEY_PART_INFO *kp= &key_info->key_part[p]; + if (kp->field != outparam->field[kp->fieldnr - 1]) { - kp.field->vcol_info = outparam->field[kp.fieldnr - 1]->vcol_info; + kp->field->vcol_info= outparam->field[kp->fieldnr - 1]->vcol_info; } } } @@ -5672,6 +5781,13 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) opt_range_condition_rows=0; no_cache= false; initialize_opt_range_structures(); + + /* + Update optimizer_costs to ensure that a SET STATEMENT of the + variables it will work. + */ + file->set_optimizer_costs(thd); + #ifdef HAVE_REPLICATION /* used in RBR Triggers */ master_had_triggers= 0; @@ -7376,7 +7492,7 @@ MY_BITMAP *TABLE::prepare_for_keyread(uint index, MY_BITMAP *map) DBUG_ENTER("TABLE::prepare_for_keyread"); if (!no_keyread) file->ha_start_keyread(index); - if (map != read_set || !(file->index_flags(index, 0, 1) & HA_CLUSTERED_INDEX)) + if (map != read_set || !is_clustering_key(index)) { mark_index_columns(index, map); column_bitmaps_set(map); @@ -8262,18 +8378,25 @@ bool TABLE::add_tmp_key(uint key, uint key_parts, DBUG_ASSERT(key < max_keys); char buf[NAME_CHAR_LEN]; - KEY* keyinfo; + KEY *keyinfo= key_info + key; + KEY_PART_INFO *key_part_info; Field **reg_field; uint i; - bool key_start= TRUE; - KEY_PART_INFO* key_part_info= - (KEY_PART_INFO*) alloc_root(&mem_root, sizeof(KEY_PART_INFO)*key_parts); - if (!key_part_info) + + keyinfo->name.length= sprintf(buf, "key%i", key); + + if (!multi_alloc_root(&mem_root, + &key_part_info, sizeof(KEY_PART_INFO)*key_parts, + &keyinfo->rec_per_key, + sizeof(key_info->rec_per_key) * key_parts, + &keyinfo->name.str, keyinfo->name.length+1, + NullS)) return TRUE; - keyinfo= key_info + key; keyinfo->key_part= key_part_info; - keyinfo->usable_key_parts= keyinfo->user_defined_key_parts = key_parts; + strmake((char*) keyinfo->name.str, buf, keyinfo->name.length); + + keyinfo->usable_key_parts= keyinfo->user_defined_key_parts= key_parts; keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; keyinfo->key_length=0; keyinfo->algorithm= HA_KEY_ALG_UNDEF; @@ -8282,14 +8405,6 @@ bool TABLE::add_tmp_key(uint key, uint key_parts, keyinfo->is_statistics_from_stat_tables= FALSE; if (unique) keyinfo->flags|= HA_NOSAME; - sprintf(buf, "key%i", key); - keyinfo->name.length= strlen(buf); - if (!(keyinfo->name.str= strmake_root(&mem_root, buf, keyinfo->name.length))) - return TRUE; - keyinfo->rec_per_key= (ulong*) alloc_root(&mem_root, - sizeof(ulong)*key_parts); - if (!keyinfo->rec_per_key) - return TRUE; bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts); keyinfo->read_stats= NULL; keyinfo->collected_stats= NULL; @@ -8307,6 +8422,11 @@ bool TABLE::add_tmp_key(uint key, uint key_parts, key_start= FALSE; key_part_info++; } + /* + We have to cache index_flags here as the table may be used by the + optimizer before it's opened. + */ + keyinfo->index_flags= file->index_flags(key, 0, 1); /* For the case when there is a derived table that would give distinct rows, @@ -8330,6 +8450,8 @@ bool TABLE::add_tmp_key(uint key, uint key_parts, set_if_bigger(s->max_key_length, keyinfo->key_length); s->keys++; + s->ext_key_parts+= keyinfo->ext_key_parts; + s->key_parts+= keyinfo->user_defined_key_parts; return FALSE; } @@ -8626,18 +8748,19 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl) index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]); } - /* - TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) - and create tbl->force_index_join instead. - Then use the correct force_index_XX instead of the global one. - */ - if (!index_join[INDEX_HINT_FORCE].is_clear_all() || - tbl->force_index_group || tbl->force_index_order) + if (!index_join[INDEX_HINT_FORCE].is_clear_all()) { - tbl->force_index= TRUE; + tbl->force_index_join= TRUE; index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]); } + /* + TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) + Use the correct force_index_XX in all places instead of the global one. + */ + tbl->force_index= (tbl->force_index_order | tbl->force_index_group | + tbl->force_index_join); + /* apply USE INDEX */ if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join) tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]); @@ -10424,10 +10547,27 @@ bool TABLE::export_structure(THD *thd, Row_definition_list *defs) inline void TABLE::initialize_opt_range_structures() { TRASH_ALLOC((void*)&opt_range_keys, sizeof(opt_range_keys)); - TRASH_ALLOC(opt_range, s->keys * sizeof(*opt_range)); + TRASH_ALLOC((void*)opt_range, s->keys * sizeof(*opt_range)); TRASH_ALLOC(const_key_parts, s->keys * sizeof(*const_key_parts)); } + +double TABLE::OPT_RANGE::index_only_fetch_cost(TABLE *table) +{ + return (table->file->cost(cost.index_cost)+ + (double) rows * table->s->optimizer_costs.key_copy_cost); +} + +void TABLE::OPT_RANGE::get_costs(ALL_READ_COST *res) +{ + res->index_cost= cost.index_cost; + res->row_cost= cost.row_cost; + res->copy_cost= cost.copy_cost; + res->max_index_blocks= max_index_blocks; + res->max_row_blocks= max_row_blocks; +} + + /* Mark table to be reopened after query */ diff --git a/sql/table.h b/sql/table.h index 5e858a24f88..add1871e899 100644 --- a/sql/table.h +++ b/sql/table.h @@ -92,6 +92,7 @@ typedef ulonglong nested_join_map; #define tmp_file_prefix "#sql" /**< Prefix for tmp tables */ #define tmp_file_prefix_length 4 #define TMP_TABLE_KEY_EXTRA 8 +#define ROCKSDB_DIRECTORY_NAME "#rocksdb" /** Enumerate possible types of a table from re-execution @@ -813,6 +814,7 @@ struct TABLE_SHARE return is_view ? view_pseudo_hton : db_plugin ? plugin_hton(db_plugin) : NULL; } + OPTIMIZER_COSTS optimizer_costs; /* Copy of get_optimizer_costs() */ enum row_type row_type; /* How rows are stored */ enum Table_type table_type; enum tmp_table_type tmp_table; @@ -888,6 +890,7 @@ struct TABLE_SHARE bool has_update_default_function; bool can_do_row_logging; /* 1 if table supports RBR */ bool long_unique_table; + bool optimizer_costs_inited; ulong table_map_id; /* for row-based replication */ @@ -1194,6 +1197,7 @@ struct TABLE_SHARE void set_overlapped_keys(); void set_ignored_indexes(); key_map usable_indexes(THD *thd); + void update_optimizer_costs(handlerton *hton); }; /* not NULL, but cannot be dereferenced */ @@ -1391,13 +1395,18 @@ public: { uint key_parts; uint ranges; - ha_rows rows; - double cost; + ha_rows rows, max_index_blocks, max_row_blocks; + Cost_estimate cost; + /* Selectivity, in case of filters */ + double selectivity; + bool first_key_part_has_only_one_value; + /* - If there is a range access by i-th index then the cost of - index only access for it is stored in index_only_costs[i] + Cost of fetching keys with index only read and returning them to the + sql level. */ - double index_only_cost; + double index_only_fetch_cost(TABLE *table); + void get_costs(ALL_READ_COST *cost); } *opt_range; /* Bitmaps of key parts that =const for the duration of join execution. If @@ -1484,6 +1493,9 @@ public: */ bool force_index; + /* Flag set when the statement contains FORCE INDEX FOR JOIN */ + bool force_index_join; + /** Flag set when the statement contains FORCE INDEX FOR ORDER BY See TABLE_LIST::process_index_hints(). @@ -1719,6 +1731,12 @@ public: uint actual_n_key_parts(KEY *keyinfo); ulong actual_key_flags(KEY *keyinfo); int update_virtual_field(Field *vf, bool ignore_warnings); + inline size_t key_storage_length(uint index) + { + if (is_clustering_key(index)) + return s->stored_rec_length; + return key_info[index].key_length + file->ref_length; + } int update_virtual_fields(handler *h, enum_vcol_update_mode update_mode); int update_default_fields(bool ignore_errors); void evaluate_update_default_function(); @@ -1783,10 +1801,12 @@ public: void prune_range_rowid_filters(); void trace_range_rowid_filters(THD *thd) const; Range_rowid_filter_cost_info * - best_range_rowid_filter_for_partial_join(uint access_key_no, - double records, - double access_cost_factor); - + best_range_rowid_filter(uint access_key_no, + double records, + double fetch_cost, + double index_only_cost, + double prev_records, + double *records_out); /** System Versioning support */ @@ -1839,7 +1859,44 @@ public: DBUG_ASSERT(s->period.name); return field[s->period.end_fieldno]; } + inline void set_cond_selectivity(double selectivity) + { + DBUG_ASSERT(selectivity >= 0.0 && selectivity <= 1.0); + cond_selectivity= selectivity; + DBUG_PRINT("info", ("cond_selectivity: %g", cond_selectivity)); + } + inline void multiply_cond_selectivity(double selectivity) + { + DBUG_ASSERT(selectivity >= 0.0 && selectivity <= 1.0); + cond_selectivity*= selectivity; + DBUG_PRINT("info", ("cond_selectivity: %g", cond_selectivity)); + } + inline void set_opt_range_condition_rows(ha_rows rows) + { + if (opt_range_condition_rows > rows) + opt_range_condition_rows= rows; + } + /* Return true if the key is a clustered key */ + inline bool is_clustering_key(uint index) const + { + return key_info[index].index_flags & HA_CLUSTERED_INDEX; + } + + /* + Return true if we can use rowid filter with this index + rowid filter can be used if + - filter pushdown is supported by the engine for the index. If this is set then + file->ha_table_flags() should not contain HA_NON_COMPARABLE_ROWID! + - The index is not a clustered primary index + */ + + inline bool can_use_rowid_filter(uint index) const + { + return ((key_info[index].index_flags & + (HA_DO_RANGE_FILTER_PUSHDOWN | HA_CLUSTERED_INDEX)) == + HA_DO_RANGE_FILTER_PUSHDOWN); + } ulonglong vers_start_id() const; ulonglong vers_end_id() const; @@ -1936,7 +1993,8 @@ class IS_table_read_plan; #define DTYPE_MERGE 4U #define DTYPE_MATERIALIZE 8U #define DTYPE_MULTITABLE 16U -#define DTYPE_MASK (DTYPE_VIEW|DTYPE_TABLE|DTYPE_MULTITABLE) +#define DTYPE_IN_PREDICATE 32U +#define DTYPE_MASK (DTYPE_VIEW|DTYPE_TABLE|DTYPE_MULTITABLE|DTYPE_IN_PREDICATE) /* Phases of derived tables/views handling, see sql_derived.cc @@ -2583,9 +2641,8 @@ struct TABLE_LIST uint outer_join; /* Which join type */ uint shared; /* Used in multi-upd */ bool updatable; /* VIEW/TABLE can be updated now */ - bool straight; /* optimize with prev table */ + bool straight; /* optimize with prev table */ bool updating; /* for replicate-do/ignore table */ - bool force_index; /* prefer index over table scan */ bool ignore_leaves; /* preload only non-leaf nodes */ bool crashed; /* Table was found crashed */ bool skip_locked; /* Skip locked in view defination */ diff --git a/sql/tztime.cc b/sql/tztime.cc index 57f1ab872ee..4d94054541d 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1623,6 +1623,8 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) DBUG_RETURN(1); thd->thread_stack= (char*) &thd; thd->store_globals(); + thd->set_query_inner((char*) STRING_WITH_LEN("intern:my_tz_init"), + default_charset_info); /* Init all memory structures that require explicit destruction */ if (my_hash_init(key_memory_tz_storage, &tz_names, &my_charset_latin1, 20, 0, diff --git a/sql/uniques.cc b/sql/uniques.cc index 572d80f0b64..36725e80a6b 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -103,7 +103,7 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, if (!max_elements) max_elements= 1; - (void) open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, + (void) open_cached_file(&file, mysql_tmpdir, TEMP_PREFIX, DISK_CHUNK_SIZE, MYF(MY_WME)); } @@ -156,10 +156,10 @@ inline double log2_n_fact(double x) the same length, so each of total_buf_size elements will be added to a sort heap with (n_buffers-1) elements. This gives the comparison cost: - total_buf_elems* log2(n_buffers) / TIME_FOR_COMPARE_ROWID; + total_buf_elems* log2(n_buffers) * ROWID_COMPARE_COST; */ -static double get_merge_buffers_cost(uint *buff_elems, uint elem_size, +static double get_merge_buffers_cost(THD *thd, uint *buff_elems, uint elem_size, uint *first, uint *last, double compare_factor) { @@ -170,9 +170,9 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size, size_t n_buffers= last - first + 1; - /* Using log2(n)=log(n)/log(2) formula */ - return 2*((double)total_buf_elems*elem_size) / IO_SIZE + - total_buf_elems*log((double) n_buffers) / (compare_factor * M_LN2); + return (2*((double)total_buf_elems*elem_size) / IO_SIZE * + default_optimizer_costs.disk_read_cost + + total_buf_elems*log2((double) n_buffers) * compare_factor); } @@ -185,6 +185,7 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size, SYNOPSIS get_merge_many_buffs_cost() + thd THD, used to get disk_read_cost buffer buffer space for temporary data, at least Unique::get_cost_calc_buff_size bytes maxbuffer # of full buffers @@ -203,7 +204,8 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size, Cost of merge in disk seeks. */ -static double get_merge_many_buffs_cost(uint *buffer, +static double get_merge_many_buffs_cost(THD *thd, + uint *buffer, uint maxbuffer, uint max_n_elems, uint last_n_elems, int elem_size, double compare_factor) @@ -231,13 +233,13 @@ static double get_merge_many_buffs_cost(uint *buffer, uint lastbuff= 0; for (i = 0; i <= (int) maxbuffer - MERGEBUFF*3/2; i += MERGEBUFF) { - total_cost+=get_merge_buffers_cost(buff_elems, elem_size, + total_cost+=get_merge_buffers_cost(thd, buff_elems, elem_size, buff_elems + i, buff_elems + i + MERGEBUFF-1, compare_factor); lastbuff++; } - total_cost+=get_merge_buffers_cost(buff_elems, elem_size, + total_cost+=get_merge_buffers_cost(thd, buff_elems, elem_size, buff_elems + i, buff_elems + maxbuffer, compare_factor); @@ -246,7 +248,7 @@ static double get_merge_many_buffs_cost(uint *buffer, } /* Simulate final merge_buff call. */ - total_cost += get_merge_buffers_cost(buff_elems, elem_size, + total_cost += get_merge_buffers_cost(thd, buff_elems, elem_size, buff_elems, buff_elems + maxbuffer, compare_factor); return total_cost; @@ -304,7 +306,7 @@ static double get_merge_many_buffs_cost(uint *buffer, these will be random seeks. */ -double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size, +double Unique::get_use_cost(THD *thd, uint *buffer, size_t nkeys, uint key_size, size_t max_in_memory_size, double compare_factor, bool intersect_fl, bool *in_memory) @@ -312,7 +314,7 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size, size_t max_elements_in_tree; size_t last_tree_elems; size_t n_full_trees; /* number of trees in unique - 1 */ - double result; + double result, disk_read_cost; max_elements_in_tree= ((size_t) max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size)); @@ -327,7 +329,7 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size, result= 2*log2_n_fact(last_tree_elems + 1.0); if (n_full_trees) result+= n_full_trees * log2_n_fact(max_elements_in_tree + 1.0); - result /= compare_factor; + result *= compare_factor; DBUG_PRINT("info",("unique trees sizes: %u=%u*%u + %u", (uint)nkeys, (uint)n_full_trees, @@ -345,14 +347,15 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size, First, add cost of writing all trees to disk, assuming that all disk writes are sequential. */ - result += DISK_SEEK_BASE_COST * n_full_trees * - ceil(((double) key_size)*max_elements_in_tree / IO_SIZE); - result += DISK_SEEK_BASE_COST * ceil(((double) key_size)*last_tree_elems / IO_SIZE); + disk_read_cost= default_optimizer_costs.disk_read_cost; + result += disk_read_cost * n_full_trees * + ceil(((double) key_size)*max_elements_in_tree / DISK_CHUNK_SIZE); + result += disk_read_cost * ceil(((double) key_size)*last_tree_elems / DISK_CHUNK_SIZE); /* Cost of merge */ if (intersect_fl) key_size+= sizeof(element_count); - double merge_cost= get_merge_many_buffs_cost(buffer, (uint)n_full_trees, + double merge_cost= get_merge_many_buffs_cost(thd, buffer, (uint)n_full_trees, (uint)max_elements_in_tree, (uint)last_tree_elems, key_size, compare_factor); @@ -361,7 +364,7 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size, Add cost of reading the resulting sequence, assuming there were no duplicate elements. */ - result += ceil((double)key_size*nkeys/IO_SIZE); + result+= (ceil((double)key_size*nkeys/IO_SIZE) * disk_read_cost); return result; } @@ -716,12 +719,12 @@ bool Unique::merge(TABLE *table, uchar *buff, size_t buff_size, /* Open cached file for table records if it isn't open */ if (! my_b_inited(outfile) && - open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, + open_cached_file(outfile, mysql_tmpdir, TEMP_PREFIX, DISK_CHUNK_SIZE, MYF(MY_WME))) return 1; bzero((char*) &sort_param,sizeof(sort_param)); - sort_param.max_rows= elements; + sort_param.limit_rows= elements; sort_param.sort_form= table; sort_param.rec_length= sort_param.sort_length= sort_param.ref_length= full_size; diff --git a/sql/uniques.h b/sql/uniques.h index 7e12a391fbd..ecc49794efe 100644 --- a/sql/uniques.h +++ b/sql/uniques.h @@ -75,10 +75,10 @@ public: inline static double get_search_cost(ulonglong tree_elems, double compare_factor) { - return log((double) tree_elems) / (compare_factor * M_LN2); + return log((double) tree_elems) * compare_factor / M_LN2; } - static double get_use_cost(uint *buffer, size_t nkeys, uint key_size, + static double get_use_cost(THD *thd, uint *buffer, size_t nkeys, uint key_size, size_t max_in_memory_size, double compare_factor, bool intersect_fl, bool *in_memory); inline static int get_cost_calc_buff_size(size_t nkeys, uint key_size, diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 19a0ffe028a..2a8deb431b1 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -132,7 +132,8 @@ extern "C" PSI_file_key arch_key_file_data; static handler *archive_create_handler(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root); -int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share); +static int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share); +static void archive_update_optimizer_costs(OPTIMIZER_COSTS *costs); /* Number of rows that will force a bulk insert. @@ -205,6 +206,7 @@ static const char *ha_archive_exts[] = { NullS }; + int archive_db_init(void *p) { DBUG_ENTER("archive_db_init"); @@ -217,10 +219,10 @@ int archive_db_init(void *p) archive_hton= (handlerton *)p; archive_hton->db_type= DB_TYPE_ARCHIVE_DB; archive_hton->create= archive_create_handler; - archive_hton->flags= HTON_NO_FLAGS; archive_hton->discover_table= archive_discover; archive_hton->tablefile_extensions= ha_archive_exts; - + archive_hton->update_optimizer_costs= archive_update_optimizer_costs; + archive_hton->flags= HTON_NO_FLAGS; DBUG_RETURN(0); } @@ -267,7 +269,7 @@ ha_archive::ha_archive(handlerton *hton, TABLE_SHARE *table_arg) archive_reader_open= FALSE; } -int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) +static int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) { DBUG_ENTER("archive_discover"); DBUG_PRINT("archive_discover", ("db: '%s' name: '%s'", share->db.str, @@ -1092,6 +1094,54 @@ int ha_archive::index_init(uint keynr, bool sorted) DBUG_RETURN(0); } +#define ARCHIVE_DECOMPRESS_TIME 0.081034543792841 // See optimizer_costs.txt + +static void archive_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + costs->disk_read_ratio= 0.20; // Assume 80 % of data is cached by system + costs->row_lookup_cost= 0; // See rnd_pos_time + costs->key_lookup_cost= 0; // See key_read_time + costs->key_next_find_cost= 0; // Only unique indexes + costs->index_block_copy_cost= 0; +} + + +IO_AND_CPU_COST ha_archive::scan_time() +{ + IO_AND_CPU_COST cost; + ulonglong blocks; + DBUG_ENTER("ha_archive::scan_time"); + + blocks= stats.data_file_length / IO_SIZE; + cost.io= 0; // No cache + cost.cpu= (blocks * DISK_READ_COST * DISK_READ_RATIO + + blocks* ARCHIVE_DECOMPRESS_TIME); + DBUG_RETURN(cost); +} + + +IO_AND_CPU_COST ha_archive::keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) +{ + IO_AND_CPU_COST cost= scan_time(); + /* + As these is an unique indexe, assume that we have to scan half the file for + each range to find the row. + */ + cost.cpu= cost.cpu * ranges / 2; + return cost; +} + + +IO_AND_CPU_COST ha_archive::rnd_pos_time(ha_rows rows) +{ + IO_AND_CPU_COST cost; + /* We have to do one azseek() for each row */ + cost.io= rows2double(rows); + cost.cpu= rows * (DISK_READ_COST * DISK_READ_RATIO + ARCHIVE_DECOMPRESS_TIME); + return cost; +} + /* No indexes, so if we get a request for an index search since we tell @@ -1116,8 +1166,6 @@ int ha_archive::index_read_idx(uchar *buf, uint index, const uchar *key, current_k_offset= mkey->key_part->offset; current_key= key; current_key_len= key_len; - - DBUG_ENTER("ha_archive::index_read_idx"); rc= rnd_init(TRUE); diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index 2bb5079868b..c96f5d8d122 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -111,6 +111,10 @@ public: uint max_supported_key_length() const { return sizeof(ulonglong); } uint max_supported_key_part_length() const { return sizeof(ulonglong); } ha_rows records() { return share->rows_recorded; } + IO_AND_CPU_COST scan_time() override; + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) override; + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) override; int index_init(uint keynr, bool sorted); virtual int index_read(uchar * buf, const uchar * key, uint key_len, enum ha_rkey_function find_flag); diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 0134032351e..343f3c70286 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -182,6 +182,17 @@ int ha_blackhole::info(uint flag) DBUG_ENTER("ha_blackhole::info"); bzero((char*) &stats, sizeof(stats)); + /* + The following is required to get replication to work as otherwise + test_quick_select() will think the table is empty and thus any + update/delete will not have any rows to update. + */ + stats.records= 2; + /* + Block size should not be 0 as this will cause division by zero + in scan_time() + */ + stats.block_size= 8192; if (flag & HA_STATUS_AUTO) stats.auto_increment_value= 1; DBUG_RETURN(0); diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore index 5923beeab93..8b032853b7a 160000 --- a/storage/columnstore/columnstore +++ b/storage/columnstore/columnstore @@ -1 +1 @@ -Subproject commit 5923beeab9397aa22563ff7b1f0f31ad8054bae6 +Subproject commit 8b032853b7a200d9af4d468ac58bb9f4b6ac7040 diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 23d3c7c1058..73dfa0af1a9 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -7400,7 +7400,8 @@ int ha_connect::multi_range_read_next(range_id_t *range_info) ha_rows ha_connect::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost) + uint *flags, ha_rows limit, + Cost_estimate *cost) { /* This call is here because there is no location where this->table would @@ -7414,7 +7415,7 @@ ha_rows ha_connect::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, *flags|= HA_MRR_USE_DEFAULT_IMPL; ha_rows rows= ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, - bufsz, flags, cost); + bufsz, flags, limit, cost); xp->g->Mrr= !(*flags & HA_MRR_USE_DEFAULT_IMPL); return rows; } // end of multi_range_read_info_const diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h index 71ceb7974ba..c83584a62e4 100644 --- a/storage/connect/ha_connect.h +++ b/storage/connect/ha_connect.h @@ -308,13 +308,18 @@ public: /** @brief Called in test_quick_select to determine if indexes should be used. */ - virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } + virtual IO_AND_CPU_COST scan_time() + { return { 0, (double) (stats.records+stats.deleted) * DISK_READ_COST }; }; /** @brief This method will never be called if you do not implement indexes. */ - virtual double read_time(uint, uint, ha_rows rows) - { return (double) rows / 20.0+1; } + virtual IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) + { + return { 0, (double) rows * 0.001 }; + } + /* Everything below are methods that we implement in ha_connect.cc. @@ -497,7 +502,8 @@ int index_prev(uchar *buf); ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost); + uint *flags, ha_rows limit, + Cost_estimate *cost); ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, uint key_parts, uint *bufsz, uint *flags, Cost_estimate *cost); diff --git a/storage/connect/mysql-test/connect/r/index.result b/storage/connect/mysql-test/connect/r/index.result index baebf1f1ebe..fdb44d06ee1 100644 --- a/storage/connect/mysql-test/connect/r/index.result +++ b/storage/connect/mysql-test/connect/r/index.result @@ -96,18 +96,25 @@ sexe genre 0 Inconnu 1 Masculin 2 Feminin -SELECT nom, prenom, genre FROM t1 NATURAL JOIN t2 LIMIT 10; +# t2 has only 3 rows. Force eq_ref by increasing table scan cost! +set @@optimizer_scan_setup_cost=10000; +explain SELECT nom, prenom, genre FROM t1 NATURAL JOIN t2 order by nom,prenom LIMIT 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4545 Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.sexe 1 Using where +SELECT nom, prenom, genre FROM t1 NATURAL JOIN t2 order by nom,prenom LIMIT 10; nom prenom genre -ESCOURCHE BENEDICTE Feminin -VICENTE LAURENCE Feminin -NICOLAS ROGER Masculin -TESSEREAU MARIE HELENE Feminin -MOGADOR ALAIN Masculin -CHAUSSEE ERIC DENIS Masculin -MAILLOT GEORGES Masculin -CAMILLE NADINE Feminin -BRUYERES JEAN MARC Masculin -LONES GERARD Masculin +ABBADIE MONIQUE Feminin +ABBAYE ANNICK Feminin +ABBAYE GERALD Masculin +ABBE KATIA Feminin +ABBE MICHELE Feminin +ABBE SOPHIE Feminin +ABBEVILLE PASCAL Masculin +ABEBERRY PATRICK Masculin +ABEILLES RENE Masculin +ABEL JEAN PIERRE Masculin +set @@optimizer_scan_setup_cost=default; # # Another table # diff --git a/storage/connect/mysql-test/connect/r/mysql_index.result b/storage/connect/mysql-test/connect/r/mysql_index.result index 54acc7be08d..b6c34add632 100644 --- a/storage/connect/mysql-test/connect/r/mysql_index.result +++ b/storage/connect/mysql-test/connect/r/mysql_index.result @@ -7,7 +7,7 @@ msg char(100) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO t1 VALUES(1,'Un'),(3,'Trois'),(5,'Cinq'); -INSERT INTO t1 VALUES(2,'Two'),(4,'Four'),(6,'Six'); +INSERT INTO t1 VALUES(2,'Two'),(4,'Four'),(6,'Six'), (7,'seven'); SELECT * FROM t1; id msg 1 Un @@ -16,6 +16,7 @@ id msg 2 Two 4 Four 6 Six +7 seven # # Make local MYSQL table with indexed id column # @@ -35,6 +36,7 @@ id msg 2 Two 4 Four 6 Six +7 seven SELECT * FROM t2 WHERE id = 3; id msg 3 Trois @@ -49,12 +51,14 @@ SELECT * FROM t2 WHERE id > 4; id msg 5 Cinq 6 Six +7 seven SELECT * FROM t2 WHERE id >= 3; id msg 3 Trois 4 Four 5 Cinq 6 Six +7 seven SELECT * FROM t2 WHERE id < 3; id msg 1 Un @@ -64,6 +68,10 @@ id msg 1 Un 5 Cinq 6 Six +7 seven +explain SELECT * FROM t2 WHERE id <= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where SELECT * FROM t2 WHERE id <= 3; id msg 1 Un @@ -87,6 +95,7 @@ id msg 4 Four 5 Cinq 6 Six +7 seven UPDATE t2 SET msg = 'Five' WHERE id = 5; Warnings: Note 1105 t1: 1 affected rows @@ -98,6 +107,7 @@ id msg 2 Two 4 Four 6 Six +7 seven DELETE FROM t2 WHERE id = 4; Warnings: Note 1105 t1: 1 affected rows @@ -108,6 +118,7 @@ id msg 5 Five 2 Two 6 Six +7 seven DROP TABLE t2; DROP TABLE t1; # diff --git a/storage/connect/mysql-test/connect/t/index.test b/storage/connect/mysql-test/connect/t/index.test index 47bfbae7680..546d5184e9f 100644 --- a/storage/connect/mysql-test/connect/t/index.test +++ b/storage/connect/mysql-test/connect/t/index.test @@ -57,8 +57,11 @@ create table t2 genre CHAR(8) NOT NULL ) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='sexe.csv' SEP_CHAR=';' ENDING=2; SELECT * FROM t2; -SELECT nom, prenom, genre FROM t1 NATURAL JOIN t2 LIMIT 10; - +--echo # t2 has only 3 rows. Force eq_ref by increasing table scan cost! +set @@optimizer_scan_setup_cost=10000; +explain SELECT nom, prenom, genre FROM t1 NATURAL JOIN t2 order by nom,prenom LIMIT 10; +SELECT nom, prenom, genre FROM t1 NATURAL JOIN t2 order by nom,prenom LIMIT 10; +set @@optimizer_scan_setup_cost=default; --echo # --echo # Another table --echo # diff --git a/storage/connect/mysql-test/connect/t/mysql_index.test b/storage/connect/mysql-test/connect/t/mysql_index.test index cb4a332cdf8..a70ea3fd6f9 100644 --- a/storage/connect/mysql-test/connect/t/mysql_index.test +++ b/storage/connect/mysql-test/connect/t/mysql_index.test @@ -30,7 +30,7 @@ CREATE TABLE t1 ( PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO t1 VALUES(1,'Un'),(3,'Trois'),(5,'Cinq'); -INSERT INTO t1 VALUES(2,'Two'),(4,'Four'),(6,'Six'); +INSERT INTO t1 VALUES(2,'Two'),(4,'Four'),(6,'Six'), (7,'seven'); SELECT * FROM t1; --echo # @@ -54,6 +54,7 @@ SELECT * FROM t2 WHERE id > 4; SELECT * FROM t2 WHERE id >= 3; SELECT * FROM t2 WHERE id < 3; SELECT * FROM t2 WHERE id < 2 OR id > 4; +explain SELECT * FROM t2 WHERE id <= 3; SELECT * FROM t2 WHERE id <= 3; SELECT * FROM t2 WHERE id BETWEEN 3 AND 5; SELECT * FROM t2 WHERE id > 2 AND id < 6; diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h index 043183444da..856bb789320 100644 --- a/storage/csv/ha_tina.h +++ b/storage/csv/ha_tina.h @@ -124,7 +124,12 @@ public: /* Called in test_quick_select to determine if indexes should be used. */ - virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } + virtual IO_AND_CPU_COST scan_time() + { + return + { (double) ((share->saved_data_file_length + IO_SIZE-1))/ IO_SIZE, + (stats.records+stats.deleted) * ROW_NEXT_FIND_COST }; + } /* The next method will never be called */ virtual bool fast_key_read() { return 1;} /* diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h index 2d3fa6d4216..92acce5b7bb 100644 --- a/storage/example/ha_example.h +++ b/storage/example/ha_example.h @@ -150,15 +150,40 @@ public: uint max_supported_key_length() const { return 0; } /** @brief - Called in test_quick_select to determine if indexes should be used. + Called in test_quick_select to determine cost of table scan */ - virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } + virtual IO_AND_CPU_COST scan_time() + { + IO_AND_CPU_COST cost; + /* 0 blocks, 0.001 ms / row */ + cost.io= (double) (stats.records+stats.deleted) * DISK_READ_COST; + cost.cpu= 0; + return cost; + } /** @brief This method will never be called if you do not implement indexes. */ - virtual double read_time(uint, uint, ha_rows rows) - { return (double) rows / 20.0+1; } + virtual IO_AND_CPU_COST keyread_time(uint, ulong, ha_rows rows, + ulonglong blocks) + { + IO_AND_CPU_COST cost; + cost.io= blocks * DISK_READ_COST; + cost.cpu= (double) rows * 0.001; + return cost; + } + + /** @brief + Cost of fetching 'rows' records through rnd_pos() + */ + virtual IO_AND_CPU_COST rnd_pos_time(ha_rows rows) + { + IO_AND_CPU_COST cost; + /* 0 blocks, 0.001 ms / row */ + cost.io= 0; + cost.cpu= (double) rows * DISK_READ_COST; + return cost; + } /* Everything below are methods that we implement in ha_example.cc. diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index faaffa21f6b..2a375a41200 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -459,6 +459,20 @@ static void init_federated_psi_keys(void) } #endif /* HAVE_PSI_INTERFACE */ +/* + Federated doesn't need costs.disk_read_ratio as everything is one a + remote server and nothing is cached locally +*/ + +static void federated_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + /* + Setting disk_read_ratios to 1.0, ensures we are using the costs + from rnd_pos_time() and scan_time() + */ + costs->disk_read_ratio= 1.0; +} + /* Initialize the federated handler. @@ -485,6 +499,7 @@ int federated_db_init(void *p) federated_hton->rollback= federated_rollback; federated_hton->create= federated_create_handler; federated_hton->drop_table= [](handlerton *, const char*) { return -1; }; + federated_hton->update_optimizer_costs= federated_update_optimizer_costs; federated_hton->flags= HTON_ALTER_NOT_SUPPORTED | HTON_NO_PARTITION; /* @@ -909,7 +924,6 @@ ha_federated::ha_federated(handlerton *hton, bzero(&bulk_insert, sizeof(bulk_insert)); } - /* Convert MySQL result set row to handler internal format @@ -2879,11 +2893,11 @@ int ha_federated::info(uint flag) &error); /* - size of IO operations (This is based on a good guess, no high science - involved) + Size of IO operations. This is used to calculate time to scan a table. + See handler.cc::keyread_time */ if (flag & HA_STATUS_CONST) - stats.block_size= 4096; + stats.block_size= 1500; // Typical size of an TCP packet } diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index 0c6285f3ac6..317271f60b4 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -180,23 +180,26 @@ public: The reason for "records * 1000" is that such a large number forces this to use indexes " */ - double scan_time() + + IO_AND_CPU_COST scan_time() { DBUG_PRINT("info", ("records %lu", (ulong) stats.records)); - return (double)(stats.records*1000); + return + { + 0, + (double) (stats.mean_rec_length * stats.records)/8192 * DISK_READ_COST+ + 1000, + }; } - /* - The next method will never be called if you do not implement indexes. - */ - double read_time(uint index, uint ranges, ha_rows rows) + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) { - /* - Per Brian, this number is bugus, but this method must be implemented, - and at a later date, he intends to document this issue for handler code - */ - return (double) rows / 20.0+1; + return {0, (double) (ranges + rows) * DISK_READ_COST }; + } + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) + { + return {0, (double) rows * DISK_READ_COST }; } - const key_map *keys_to_use_for_scanning() { return &key_map_full; } /* Everything below are methods that we implment in ha_federated.cc. @@ -240,16 +243,11 @@ public: void position(const uchar *record); //required /* A ref is a pointer inside a local buffer. It is not comparable to - other ref's. This is never called as HA_NON_COMPARABLE_ROWID is set. + other ref's. */ int cmp_ref(const uchar *ref1, const uchar *ref2) { -#ifdef NOT_YET - DBUG_ASSERT(0); - return 0; -#else - return handler::cmp_ref(ref1,ref2); /* Works if table scan is used */ -#endif + return handler::cmp_ref(ref1,ref2); /* Works if table scan is used */ } int info(uint); //required int extra(ha_extra_function operation); @@ -285,4 +283,3 @@ public: int execute_simple_query(const char *query, int len); int reset(void); }; - diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 6199504e04f..a39e707b401 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -411,6 +411,20 @@ create_federatedx_derived_handler(THD* thd, TABLE_LIST *derived); static select_handler* create_federatedx_select_handler(THD* thd, SELECT_LEX *sel); +/* + Federated doesn't need costs.disk_read_ratio as everything is one a remote + server and nothing is cached locally +*/ + +static void federatedx_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + /* + Setting disk_read_ratios to 1.0, ensures we are using the costs + from rnd_pos_time() and scan_time() + */ + costs->disk_read_ratio= 0.0; +} + /* Initialize the federatedx handler. @@ -443,6 +457,7 @@ int federatedx_db_init(void *p) federatedx_hton->flags= HTON_ALTER_NOT_SUPPORTED; federatedx_hton->create_derived= create_federatedx_derived_handler; federatedx_hton->create_select= create_federatedx_select_handler; + federatedx_hton->update_optimizer_costs= federatedx_update_optimizer_costs; if (mysql_mutex_init(fe_key_mutex_federatedx, &federatedx_mutex, MY_MUTEX_INIT_FAST)) @@ -3098,11 +3113,11 @@ int ha_federatedx::info(uint flag) if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST)) { /* - size of IO operations (This is based on a good guess, no high science - involved) + Size of IO operations. This is used to calculate time to scan a table. + See handler.cc::keyread_time */ if (flag & HA_STATUS_CONST) - stats.block_size= 4096; + stats.block_size= 1500; // Typical size of an TCP packet if ((*iop)->table_metadata(&stats, share->table_name, (uint)share->table_name_length, flag)) diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index 3eb7a9c662c..6876db5cbb8 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -222,7 +222,6 @@ public: virtual int seek_position(FEDERATEDX_IO_RESULT **io_result, const void *ref)=0; virtual void set_thd(void *thd) { } - }; @@ -365,29 +364,31 @@ public: Talk to Kostja about this - how to get the number of rows * ... disk scan time on other side (block size, size of the row) + network time ... - The reason for "records * 1000" is that such a large number forces - this to use indexes " + The reason for "1000" is that such a large number forces this to use indexes " */ - double scan_time() + IO_AND_CPU_COST scan_time() { DBUG_PRINT("info", ("records %lu", (ulong) stats.records)); - return (double)(stats.records*1000); + return + { + 0, + (double) (stats.mean_rec_length * stats.records)/8192 * DISK_READ_COST+ + 1000, + }; } - /* - The next method will never be called if you do not implement indexes. - */ - double read_time(uint index, uint ranges, ha_rows rows) + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) { - /* - Per Brian, this number is bugus, but this method must be implemented, - and at a later date, he intends to document this issue for handler code - */ - return (double) rows / 20.0+1; + return {0, (double) (ranges + rows) * DISK_READ_COST }; + } + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) + { + return {0, (double) rows * DISK_READ_COST }; } const key_map *keys_to_use_for_scanning() { return &key_map_full; } /* - Everything below are methods that we implment in ha_federatedx.cc. + Everything below are methods that we implement in ha_federatedx.cc. Most of these methods are not obligatory, skip them and MySQL will treat them as not implemented diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 5f7f0c1efa0..cc7dc79e508 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -42,6 +42,28 @@ static int heap_drop_table(handlerton *hton, const char *path) return error == ENOENT ? -1 : error; } +/* See optimizer_costs.txt for how the following values where calculated */ +#define HEAP_ROW_NEXT_FIND_COST 8.0166e-06 // For table scan +#define BTREE_KEY_NEXT_FIND_COST 0.00007739 // For binary tree scan +#define HEAP_LOOKUP_COST 0.00016097 // Heap lookup cost + +static void heap_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + /* + A lot of values are 0 as heap supports all needed xxx_time() functions + */ + costs->disk_read_cost=0; // All data in memory + costs->disk_read_ratio= 0.0; // All data in memory + costs->key_next_find_cost= 0; + costs->key_copy_cost= 0; // Set in keyread_time() + costs->row_copy_cost= 2.334e-06; // This is small as its just a memcpy + costs->row_lookup_cost= 0; // Direct pointer + costs->row_next_find_cost= 0; + costs->key_lookup_cost= 0; + costs->key_next_find_cost= 0; + costs->index_block_copy_cost= 0; +} + int heap_init(void *p) { handlerton *heap_hton; @@ -53,6 +75,7 @@ int heap_init(void *p) heap_hton->create= heap_create_handler; heap_hton->panic= heap_panic; heap_hton->drop_table= heap_drop_table; + heap_hton->update_optimizer_costs= heap_update_optimizer_costs; heap_hton->flags= HTON_CAN_RECREATE; return 0; @@ -73,7 +96,8 @@ static handler *heap_create_handler(handlerton *hton, ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), file(0), records_changed(0), key_stat_version(0), internal_table(0) -{} +{ +} /* Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to @@ -228,6 +252,41 @@ void ha_heap::update_key_stats() } +IO_AND_CPU_COST ha_heap::keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) +{ + KEY *key=table->key_info+index; + if (key->algorithm == HA_KEY_ALG_BTREE) + { + double lookup_cost; + lookup_cost= ranges * costs->key_cmp_cost * log2(stats.records+1); + return {0, ranges * lookup_cost + (rows-ranges) * BTREE_KEY_NEXT_FIND_COST }; + } + else + { + return {0, (ranges * HEAP_LOOKUP_COST + + (rows-ranges) * BTREE_KEY_NEXT_FIND_COST) }; + } +} + + +IO_AND_CPU_COST ha_heap::scan_time() +{ + return {0, (double) (stats.records+stats.deleted) * HEAP_ROW_NEXT_FIND_COST }; +} + + +IO_AND_CPU_COST ha_heap::rnd_pos_time(ha_rows rows) +{ + /* + The row pointer is a direct pointer to the block. Thus almost instant + in practice. + Note that ha_rnd_pos_time() will add ROW_COPY_COST to this result + */ + return { 0, 0 }; +} + + int ha_heap::write_row(const uchar * buf) { int res; diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index 3a41028c719..beb97601c06 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -37,15 +37,15 @@ class ha_heap final : public handler public: ha_heap(handlerton *hton, TABLE_SHARE *table); ~ha_heap() {} - handler *clone(const char *name, MEM_ROOT *mem_root); - const char *index_type(uint inx) + handler *clone(const char *name, MEM_ROOT *mem_root) override; + const char *index_type(uint inx) override { return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? "BTREE" : "HASH"); } /* Rows also use a fixed-size format */ - enum row_type get_row_type() const { return ROW_TYPE_FIXED; } - ulonglong table_flags() const + enum row_type get_row_type() const override { return ROW_TYPE_FIXED; } + ulonglong table_flags() const override { return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | @@ -53,73 +53,73 @@ public: HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS | HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT | HA_CAN_HASH_KEYS); } - ulong index_flags(uint inx, uint part, bool all_parts) const + ulong index_flags(uint inx, uint part, bool all_parts) const override { return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE : HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR); } - const key_map *keys_to_use_for_scanning() { return &btree_keys; } - uint max_supported_keys() const { return MAX_KEY; } - uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; } - double scan_time() - { return (double) (stats.records+stats.deleted) / 20.0+10; } - double read_time(uint index, uint ranges, ha_rows rows) - { return (double) (rows +1)/ 20.0; } - double keyread_time(uint index, uint ranges, ha_rows rows) - { return (double) (rows + ranges) / 20.0 ; } - double avg_io_cost() - { return 0.05; } /* 1/20 */ - int open(const char *name, int mode, uint test_if_locked); - int close(void); - void set_keys_for_scanning(void); - int write_row(const uchar * buf); - int update_row(const uchar * old_data, const uchar * new_data); - int delete_row(const uchar * buf); - virtual void get_auto_increment(ulonglong offset, ulonglong increment, - ulonglong nb_desired_values, - ulonglong *first_value, - ulonglong *nb_reserved_values); + const key_map *keys_to_use_for_scanning() override { return &btree_keys; } + uint max_supported_keys() const override { return MAX_KEY; } + uint max_supported_key_part_length() const override { return MAX_KEY_LENGTH; } + IO_AND_CPU_COST scan_time() override; + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) override; + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) override; + /* 0 for avg_io_cost ensures that there are no read-block calculations */ + + int open(const char *name, int mode, uint test_if_locked) override; + int close(void) override; + int write_row(const uchar * buf) override; + int update_row(const uchar * old_data, const uchar * new_data) override; + int delete_row(const uchar * buf) override; + void get_auto_increment(ulonglong offset, ulonglong increment, + ulonglong nb_desired_values, + ulonglong *first_value, + ulonglong *nb_reserved_values) override; int index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, - enum ha_rkey_function find_flag); - int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map); + enum ha_rkey_function find_flag) override; + int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map) + override; int index_read_idx_map(uchar * buf, uint index, const uchar * key, key_part_map keypart_map, - enum ha_rkey_function find_flag); - int index_next(uchar * buf); - int index_prev(uchar * buf); - int index_first(uchar * buf); - int index_last(uchar * buf); - int rnd_init(bool scan); - int rnd_next(uchar *buf); - int rnd_pos(uchar * buf, uchar *pos); - void position(const uchar *record); - int can_continue_handler_scan(); - int info(uint); - int extra(enum ha_extra_function operation); - int reset(); - int external_lock(THD *thd, int lock_type); - int delete_all_rows(void); - int reset_auto_increment(ulonglong value); - int disable_indexes(uint mode); - int enable_indexes(uint mode); - int indexes_are_disabled(void); + enum ha_rkey_function find_flag) override; + int index_next(uchar * buf) override; + int index_prev(uchar * buf) override; + int index_first(uchar * buf) override; + int index_last(uchar * buf) override; + int rnd_init(bool scan) override; + int rnd_next(uchar *buf) override; + int rnd_pos(uchar * buf, uchar *pos) override; + void position(const uchar *record) override; + int can_continue_handler_scan() override; + int info(uint) override; + int extra(enum ha_extra_function operation) override; + int reset() override; + int external_lock(THD *thd, int lock_type) override; + int delete_all_rows(void) override; + int reset_auto_increment(ulonglong value) override; + int disable_indexes(uint mode) override; + int enable_indexes(uint mode) override; + int indexes_are_disabled(void) override; ha_rows records_in_range(uint inx, const key_range *start_key, - const key_range *end_key, page_range *pages); - int delete_table(const char *from); - void drop_table(const char *name); - int rename_table(const char * from, const char * to); - int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); - void update_create_info(HA_CREATE_INFO *create_info); + const key_range *end_key, page_range *pages) override; + int delete_table(const char *from) override; + void drop_table(const char *name) override; + int rename_table(const char * from, const char * to) override; + int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info) override; + void update_create_info(HA_CREATE_INFO *create_info) override; THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, - enum thr_lock_type lock_type); - int cmp_ref(const uchar *ref1, const uchar *ref2) + enum thr_lock_type lock_type) override; + int cmp_ref(const uchar *ref1, const uchar *ref2) override { return memcmp(ref1, ref2, sizeof(HEAP_PTR)); } - bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); - int find_unique_row(uchar *record, uint unique_idx); + bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes) + override; + int find_unique_row(uchar *record, uint unique_idx) override; private: void update_key_stats(); + void set_keys_for_scanning(void); }; diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 296b2c904f3..6528eb0173f 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -5134,6 +5134,7 @@ search_loop: DBUG_EXECUTE_IF("bug14007649", DBUG_RETURN(n_rows);); +#ifdef NOT_USED /* Do not estimate the number of rows in the range to over 1 / 2 of the estimated rows in the whole table */ @@ -5148,6 +5149,10 @@ search_loop: if (n_rows == 0) n_rows= table_n_rows; } +#else + if (n_rows > table_n_rows) + n_rows= table_n_rows; +#endif DBUG_RETURN(n_rows); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ee647430098..7cba8c46fff 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4019,6 +4019,26 @@ skip_buffering_tweak: DBUG_RETURN(0); } + +/*********************************************************************//** +Setup costs factors for InnoDB to be able to approximate how many +ms different opperations takes. See cost functions in handler.h how +the different variables are used */ + +static void innobase_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + /* + The following number was found by check_costs.pl when using 1M rows + and all rows are cached. See optimizer_costs.txt for details + */ + costs->row_next_find_cost= 0.00007013; + costs->row_lookup_cost= 0.00076597; + costs->key_next_find_cost= 0.00009900; + costs->key_lookup_cost= 0.00079112; + costs->row_copy_cost= 0.00006087; +} + + /** Initialize the InnoDB storage engine plugin. @param[in,out] p InnoDB handlerton @return error code @@ -4086,6 +4106,8 @@ static int innodb_init(void* p) innobase_hton->prepare_commit_versioned = innodb_prepare_commit_versioned; + innobase_hton->update_optimizer_costs= innobase_update_optimizer_costs; + innodb_remember_check_sysvar_funcs(); compile_time_assert(DATA_MYSQL_TRUE_VARCHAR == MYSQL_TYPE_VARCHAR); @@ -5017,13 +5039,11 @@ ha_innobase::index_flags( } ulong flags= key == table_share->primary_key - ? HA_CLUSTERED_INDEX : 0; + ? HA_CLUSTERED_INDEX : HA_KEYREAD_ONLY | HA_DO_RANGE_FILTER_PUSHDOWN; flags |= HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER - | HA_READ_RANGE | HA_KEYREAD_ONLY - | HA_DO_INDEX_COND_PUSHDOWN - | HA_DO_RANGE_FILTER_PUSHDOWN; - + | HA_READ_RANGE + | HA_DO_INDEX_COND_PUSHDOWN; return(flags); } @@ -9445,6 +9465,11 @@ ha_innobase::ft_init() trx->will_lock = true; } + /* If there is an FTS scan in progress, stop it */ + fts_result_t* result = (reinterpret_cast(ft_handler))->ft_result; + if (result) + result->current= NULL; + DBUG_RETURN(rnd_init(false)); } @@ -14287,13 +14312,15 @@ ha_innobase::estimate_rows_upper_bound() DBUG_RETURN((ha_rows) estimate); } + /*********************************************************************//** How many seeks it will take to read through the table. This is to be comparable to the number returned by records_in_range so that we can decide if we should scan the table or use keys. @return estimated time measured in disk seeks */ -double +#ifdef NOT_USED +IO_AND_CPU_COST ha_innobase::scan_time() /*====================*/ { @@ -14313,24 +14340,28 @@ ha_innobase::scan_time() TODO: This will be further improved to return some approximate estimate but that would also needs pre-population of stats structure. As of now approach is in sync with MyISAM. */ - return(ulonglong2double(stats.data_file_length) / IO_SIZE + 2); + return { (ulonglong2double(stats.data_file_length) / IO_SIZE * DISK_READ_COST), 0.0 }; } ulint stat_clustered_index_size; - + IO_AND_CPU_COST cost; ut_a(m_prebuilt->table->stat_initialized); stat_clustered_index_size = m_prebuilt->table->stat_clustered_index_size; - return((double) stat_clustered_index_size); + cost.io= (double) stat_clustered_index_size * DISK_READ_COST; + cost.cpu= 0; + return(cost); } +#endif /******************************************************************//** Calculate the time it takes to read a set of ranges through an index This enables us to optimise reads for clustered indexes. @return estimated time measured in disk seeks */ +#ifdef NOT_USED double ha_innobase::read_time( /*===================*/ @@ -14355,9 +14386,34 @@ ha_innobase::read_time( return(time_for_scan); } - return(ranges + (double) rows / (double) total_rows * time_for_scan); + return(ranges * KEY_LOOKUP_COST + (double) rows / (double) total_rows * time_for_scan); } +/******************************************************************//** +Calculate the time it takes to read a set of rows with primary key. +*/ + +IO_AND_CPU_COST +ha_innobase::rnd_pos_time(ha_rows rows) +{ + ha_rows total_rows; + + /* Assume that the read time is proportional to the scan time for all + rows + at most one seek per range. */ + + IO_AND_CPU_COST time_for_scan = scan_time(); + + if ((total_rows = estimate_rows_upper_bound()) < rows) { + + return(time_for_scan); + } + double frac= (double) rows + (double) rows / (double) total_rows; + time_for_scan.io*= frac; + time_for_scan.cpu*= frac; + return(time_for_scan); +} +#endif + /*********************************************************************//** Calculates the key number used inside MySQL for an Innobase index. @return the key number used inside MySQL */ @@ -14835,13 +14891,6 @@ ha_innobase::info_low( innodb_rec_per_key(index, j, stats.records)); - /* Since MySQL seems to favor table scans - too much over index searches, we pretend - index selectivity is 2 times better than - our estimate: */ - - rec_per_key_int = rec_per_key_int / 2; - if (rec_per_key_int == 0) { rec_per_key_int = 1; } @@ -19919,6 +19968,7 @@ ha_innobase::multi_range_read_info_const( uint n_ranges, uint* bufsz, uint* flags, + ha_rows limit, Cost_estimate* cost) { /* See comments in ha_myisam::multi_range_read_info_const */ @@ -19928,8 +19978,9 @@ ha_innobase::multi_range_read_info_const( *flags |= HA_MRR_USE_DEFAULT_IMPL; } - ha_rows res= m_ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, - bufsz, flags, cost); + ha_rows res= m_ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, + n_ranges, + bufsz, flags, limit, cost); return res; } diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 1f42bf180a8..60b56b4a22f 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -105,10 +105,10 @@ public: int close(void) override; - double scan_time() override; - - double read_time(uint index, uint ranges, ha_rows rows) override; - +#ifdef NOT_USED + IO_AND_CPU_COST scan_time() override; + double rnd_pos_time(ha_rows rows) override; +#endif int write_row(const uchar * buf) override; int update_row(const uchar * old_data, const uchar * new_data) override; @@ -383,6 +383,7 @@ public: uint n_ranges, uint* bufsz, uint* flags, + ha_rows limit, Cost_estimate* cost) override; /** Initialize multi range read and get information. diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 13af09361be..fa7e129752a 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4040,7 +4040,8 @@ row_search_idx_cond_check( ut_ad(rec_offs_validate(rec, prebuilt->index, offsets)); if (!prebuilt->idx_cond) { - if (!handler_rowid_filter_is_active(prebuilt->pk_filter)) { + if (!prebuilt->pk_filter || + !handler_rowid_filter_is_active(prebuilt->pk_filter)) { return(CHECK_POS); } } else { @@ -4082,7 +4083,8 @@ row_search_idx_cond_check( switch (result) { case CHECK_POS: - if (handler_rowid_filter_is_active(prebuilt->pk_filter)) { + if (prebuilt->pk_filter && + handler_rowid_filter_is_active(prebuilt->pk_filter)) { ut_ad(!prebuilt->index->is_primary()); if (prebuilt->clust_index_was_generated) { ulint len; diff --git a/storage/maria/aria_chk.c b/storage/maria/aria_chk.c index 92a9945e3ba..61821ec9099 100644 --- a/storage/maria/aria_chk.c +++ b/storage/maria/aria_chk.c @@ -1618,6 +1618,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) pos=strmov(pos,"sorted index pages,"); if (!(share->state.changed & STATE_NOT_ZEROFILLED)) pos=strmov(pos,"zerofilled,"); + if (test_all_bits(share->state.changed, (STATE_NOT_ZEROFILLED | STATE_HAS_LSN))) + pos=strmov(pos,"has_lsn,"); if (!(share->state.changed & STATE_NOT_MOVABLE)) pos=strmov(pos,"movable,"); if (have_control_file && (share->state.changed & STATE_MOVED)) diff --git a/storage/maria/aria_read_log.c b/storage/maria/aria_read_log.c index c0c76ed5590..85a6f4a5e97 100644 --- a/storage/maria/aria_read_log.c +++ b/storage/maria/aria_read_log.c @@ -139,6 +139,12 @@ int main(int argc, char **argv) if (opt_display_only) printf("You are using --display-only, NOTHING will be written to disk\n"); + if (translog_get_horizon() == LSN_IMPOSSIBLE) + { + fprintf(stdout, "The transaction log is empty\n"); + goto end; + } + lsn= translog_first_lsn_in_log(); if (lsn == LSN_ERROR) { @@ -147,7 +153,8 @@ int main(int argc, char **argv) } if (lsn == LSN_IMPOSSIBLE) { - fprintf(stdout, "The transaction log is empty\n"); + fprintf(stdout, "The transaction log is empty\n"); + goto end; } if (opt_start_from_checkpoint && !opt_start_from_lsn && last_checkpoint_lsn != LSN_IMPOSSIBLE) @@ -300,7 +307,7 @@ static struct my_option my_long_options[] = static void print_version(void) { - printf("%s Ver 1.5 for %s on %s\n", + printf("%s Ver 1.6 for %s on %s\n", my_progname_short, SYSTEM_TYPE, MACHINE_TYPE); } @@ -308,7 +315,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright (C) 2007 MySQL AB, 2009-2011 Monty Program Ab, 2020 MariaDB Corporation"); + puts("Copyright (C) 2007 MySQL AB, 2009-2011 Monty Program Ab, 2022 MariaDB Corporation"); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); puts("and you are welcome to modify and redistribute it under the GPL license\n"); diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 21d9a00b94e..8f59ce0a549 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1094,21 +1094,52 @@ ulong ha_maria::index_flags(uint inx, uint part, bool all_parts) const } else { - flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE | - HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN; + flags= (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE | + HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN | + HA_DO_RANGE_FILTER_PUSHDOWN); } return flags; } -double ha_maria::scan_time() +/* + Update costs that are unique for this TABLE instance +*/ + +void ha_maria::update_optimizer_costs(OPTIMIZER_COSTS *costs) { - if (file->s->data_file_type == BLOCK_RECORD) - return (ulonglong2double(stats.data_file_length - file->s->block_size) / - file->s->block_size) + 2; - return handler::scan_time(); + /* + Default costs for Aria with BLOCK_FORMAT is the same as MariaDB default + costs. + */ + if (file->s->data_file_type != BLOCK_RECORD) + { + /* + MyISAM format row lookup costs are slow as the row data is on a not + cached file. Costs taken from ha_myisam.cc + */ + costs->row_next_find_cost= 0.000063539; + costs->row_lookup_cost= 0.001014818; + } } + +IO_AND_CPU_COST ha_maria::rnd_pos_time(ha_rows rows) +{ + IO_AND_CPU_COST cost= handler::rnd_pos_time(rows); + /* file may be 0 if this is an internal temporary file that is not yet opened */ + if (file && file->s->data_file_type != BLOCK_RECORD) + { + /* + Row data is not cached. costs.row_lookup_cost includes the cost of + the reading the row from system (probably cached by the OS). + */ + cost.io= 0; + } + return cost; +} + + /* We need to be able to store at least 2 keys on an index page as the splitting algorithms depends on this. (With only one key on a page @@ -2505,10 +2536,12 @@ int ha_maria::index_read_idx_map(uchar * buf, uint index, const uchar * key, end_range= NULL; if (index == pushed_idx_cond_keyno) ma_set_index_cond_func(file, handler_index_cond_check, this); + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + ma_set_rowid_filter_func(file, handler_rowid_filter_check, this); error= maria_rkey(file, buf, index, key, keypart_map, find_flag); - ma_set_index_cond_func(file, NULL, 0); + ma_reset_index_filter_functions(file); return error; } @@ -2582,18 +2615,22 @@ int ha_maria::index_next_same(uchar * buf, int ha_maria::index_init(uint idx, bool sorted) { - active_index=idx; + active_index= idx; if (pushed_idx_cond_keyno == idx) ma_set_index_cond_func(file, handler_index_cond_check, this); + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + ma_set_rowid_filter_func(file, handler_rowid_filter_check, this); return 0; } - int ha_maria::index_end() { + /* + in_range_check_pushed_down and index_id_cond_keyno are reset in + handler::cancel_pushed_idx_cond() + */ active_index=MAX_KEY; - ma_set_index_cond_func(file, NULL, 0); - in_range_check_pushed_down= FALSE; + ma_reset_index_filter_functions(file); ds_mrr.dsmrr_close(); return 0; } @@ -2690,15 +2727,21 @@ int ha_maria::info(uint flag) share->db_record_offset= maria_info.record_offset; if (share->key_parts) { - ulong *to= table->key_info[0].rec_per_key, *end; double *from= maria_info.rec_per_key; - for (end= to+ share->key_parts ; to < end ; to++, from++) - *to= (ulong) (*from + 0.5); + KEY *key, *key_end; + for (key= table->key_info, key_end= key + share->keys; + key < key_end ; key++) + { + ulong *to= key->rec_per_key; + for (ulong *end= to+ key->user_defined_key_parts ; + to < end ; + to++, from++) + *to= (ulong) (*from + 0.5); + } } - /* - Set data_file_name and index_file_name to point at the symlink value - if table is symlinked (Ie; Real name is not same as generated name) + Set data_file_name and index_file_name to point at the symlink value + if table is symlinked (Ie; Real name is not same as generated name) */ data_file_name= index_file_name= 0; fn_format(name_buff, file->s->open_file_name.str, "", MARIA_NAME_DEXT, @@ -2781,7 +2824,7 @@ int ha_maria::extra(enum ha_extra_function operation) int ha_maria::reset(void) { - ma_set_index_cond_func(file, NULL, 0); + ma_reset_index_filter_functions(file); ds_mrr.dsmrr_close(); if (file->trn) { @@ -3839,6 +3882,10 @@ bool ha_maria::is_changed() const return file->state->changed; } +static void aria_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ +} + static int ha_maria_init(void *p) { @@ -3871,6 +3918,7 @@ static int ha_maria_init(void *p) maria_hton->show_status= maria_show_status; maria_hton->prepare_for_backup= maria_prepare_for_backup; maria_hton->end_backup= maria_end_backup; + maria_hton->update_optimizer_costs= aria_update_optimizer_costs; /* TODO: decide if we support Maria being used for log tables */ maria_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES | @@ -4171,7 +4219,8 @@ int ha_maria::multi_range_read_next(range_id_t *range_info) ha_rows ha_maria::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost) + uint *flags, ha_rows limit, + Cost_estimate *cost) { /* This call is here because there is no location where this->table would @@ -4180,7 +4229,7 @@ ha_rows ha_maria::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, */ ds_mrr.init(this, table); return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, - flags, cost); + flags, limit, cost); } ha_rows ha_maria::multi_range_read_info(uint keyno, uint n_ranges, uint keys, @@ -4231,6 +4280,26 @@ Item *ha_maria::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) return NULL; } +bool ha_maria::rowid_filter_push(Rowid_filter* rowid_filter) +{ + /* This will be used in index_init() */ + pushed_rowid_filter= rowid_filter; + return false; +} + + +/* Enable / disable rowid filter depending if it's active or not */ + +void ha_maria::rowid_filter_changed() +{ + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + ma_set_rowid_filter_func(file, handler_rowid_filter_check, this); + else + ma_set_rowid_filter_func(file, NULL, this); +} + + + /** Find record by unique constrain (used in temporary tables) diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index 6b4302145dd..bea913e424f 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -77,8 +77,6 @@ public: { return max_supported_key_length(); } enum row_type get_row_type() const override final; void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) override final; - virtual double scan_time() override final; - int open(const char *name, int mode, uint test_if_locked) override; int close(void) override final; int write_row(const uchar * buf) override; @@ -114,6 +112,8 @@ public: int remember_rnd_pos() override final; int restart_rnd_next(uchar * buf) override final; void position(const uchar * record) override final; + void update_optimizer_costs(OPTIMIZER_COSTS *costs) override final; + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) override final; int info(uint) override final; int info(uint, my_bool); int extra(enum ha_extra_function operation) override final; @@ -175,7 +175,8 @@ public: ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost) override final; + uint *flags, ha_rows limit, + Cost_estimate *cost) override final; ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, uint key_parts, uint *bufsz, uint *flags, Cost_estimate *cost) override final; @@ -183,6 +184,8 @@ public: /* Index condition pushdown implementation */ Item *idx_cond_push(uint keyno, Item* idx_cond) override final; + bool rowid_filter_push(Rowid_filter* rowid_filter) override; + void rowid_filter_changed() override; int find_unique_row(uchar *record, uint unique_idx) override final; diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index f470d3691c1..45d6df7a63a 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -3651,28 +3651,35 @@ err: int maria_zerofill(HA_CHECK *param, MARIA_HA *info, const char *name) { - my_bool error, reenable_logging, + my_bool error= 0, reenable_logging, zero_lsn= !(param->testflag & T_ZEROFILL_KEEP_LSN); MARIA_SHARE *share= info->s; DBUG_ENTER("maria_zerofill"); if ((reenable_logging= share->now_transactional)) _ma_tmp_disable_logging_for_table(info, 0); - if (!(error= (maria_zerofill_index(param, info, name) || - maria_zerofill_data(param, info, name) || - _ma_set_uuid(info->s, 0)))) + + if (share->state.changed & (STATE_NOT_ZEROFILLED | (zero_lsn ? STATE_HAS_LSN : 0))) + error= (maria_zerofill_index(param, info, name) || + maria_zerofill_data(param, info, name)); + if (!error) + error= _ma_set_uuid(info->s, 0); + + if (!error) { /* - Mark that we have done zerofill of data and index. If we zeroed pages' - LSN, table is movable. + Mark that we have done zerofill of data and index. If we zeroed the LSN + on the pages, table is movable. */ share->state.changed&= ~STATE_NOT_ZEROFILLED; if (zero_lsn) { - share->state.changed&= ~(STATE_NOT_MOVABLE | STATE_MOVED); + share->state.changed&= ~(STATE_NOT_MOVABLE | STATE_MOVED | STATE_HAS_LSN); /* Table should get new LSNs */ share->state.create_rename_lsn= share->state.is_of_horizon= share->state.skip_redo_lsn= LSN_NEEDS_NEW_STATE_LSNS; } + else + share->state.changed|= STATE_HAS_LSN; /* Ensure state is later flushed to disk, if within maria_chk */ info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c index 21befb70bd9..237b75b99b7 100644 --- a/storage/maria/ma_control_file.c +++ b/storage/maria/ma_control_file.c @@ -104,7 +104,7 @@ one should increment the control file version number. This LSN serves for the two-checkpoint rule, and also to find the checkpoint record when doing a recovery. */ -LSN last_checkpoint_lsn= LSN_IMPOSSIBLE; +volatile LSN last_checkpoint_lsn= LSN_IMPOSSIBLE; uint32 last_logno= FILENO_IMPOSSIBLE; /** The maximum transaction id given to a transaction. It is only updated at diff --git a/storage/maria/ma_control_file.h b/storage/maria/ma_control_file.h index 40428f665f4..c74957b8322 100644 --- a/storage/maria/ma_control_file.h +++ b/storage/maria/ma_control_file.h @@ -37,7 +37,7 @@ C_MODE_START LSN of the last checkoint (if last_checkpoint_lsn == LSN_IMPOSSIBLE then there was never a checkpoint) */ -extern LSN last_checkpoint_lsn; +extern volatile LSN last_checkpoint_lsn; /* Last log number (if last_logno == FILENO_IMPOSSIBLE then there is no log file yet) diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c index 425cb421e22..087100e3d8c 100644 --- a/storage/maria/ma_extra.c +++ b/storage/maria/ma_extra.c @@ -510,8 +510,17 @@ void ma_set_index_cond_func(MARIA_HA *info, index_cond_func_t func, { info->index_cond_func= func; info->index_cond_func_arg= func_arg; + info->has_cond_pushdown= (info->index_cond_func || info->rowid_filter_func); } +void ma_set_rowid_filter_func(MARIA_HA *info, + rowid_filter_func_t check_func, + void *func_arg) +{ + info->rowid_filter_func= check_func; + info->rowid_filter_func_arg= func_arg; + info->has_cond_pushdown= (info->index_cond_func || info->rowid_filter_func); +} /* Start/Stop Inserting Duplicates Into a Table, WL#1648. diff --git a/storage/maria/ma_info.c b/storage/maria/ma_info.c index ddf92654be0..3de6b8b74c5 100644 --- a/storage/maria/ma_info.c +++ b/storage/maria/ma_info.c @@ -20,14 +20,6 @@ #include #endif - /* Get position to last record */ - -MARIA_RECORD_POS maria_position(MARIA_HA *info) -{ - return info->cur_row.lastpos; -} - - uint maria_max_key_length() { uint tmp= (_ma_max_key_length() - 8 - HA_MAX_KEY_SEG*3); diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c index d47e8cf715a..1b58c1c12c8 100644 --- a/storage/maria/ma_key.c +++ b/storage/maria/ma_key.c @@ -678,22 +678,44 @@ int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos) CHECK_OUT_OF_RANGE to indicate that we don't have any active row. */ -check_result_t ma_check_index_cond(register MARIA_HA *info, uint keynr, - uchar *record) +check_result_t ma_check_index_cond_real(register MARIA_HA *info, uint keynr, + uchar *record) { check_result_t res= CHECK_POS; + DBUG_ASSERT(info->index_cond_func || info->rowid_filter_func); + + if (_ma_put_key_in_record(info, keynr, FALSE, record)) + { + /* Impossible case; Can only happen if bug in code */ + _ma_print_error(info, HA_ERR_CRASHED, 0); + info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */ + my_errno= HA_ERR_CRASHED; + return CHECK_ERROR; + } + if (info->index_cond_func) { - if (_ma_put_key_in_record(info, keynr, FALSE, record)) + if ((res= info->index_cond_func(info->index_cond_func_arg)) == + CHECK_OUT_OF_RANGE) { - /* Impossible case; Can only happen if bug in code */ - _ma_print_error(info, HA_ERR_CRASHED, 0); + /* We got beyond the end of scanned range */ info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */ - my_errno= HA_ERR_CRASHED; - res= CHECK_ERROR; + my_errno= HA_ERR_END_OF_FILE; + return res; } - else if ((res= info->index_cond_func(info->index_cond_func_arg)) == - CHECK_OUT_OF_RANGE) + /* + If we got an error, out-of-range condition, or ICP condition computed to + FALSE - we don't need to check the Rowid Filter. + */ + if (res != CHECK_POS) + return res; + } + + /* Check the Rowid Filter, if present */ + if (info->rowid_filter_func) + { + if ((res= info->rowid_filter_func(info->rowid_filter_func_arg)) == + CHECK_OUT_OF_RANGE) { /* We got beyond the end of scanned range */ info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */ diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 8e6426e3aa4..c3615e5271c 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -478,7 +478,7 @@ static my_bool translog_page_validator(int res, PAGECACHE_IO_HOOK_ARGS *args); static my_bool translog_get_next_chunk(TRANSLOG_SCANNER_DATA *scanner); static uint32 translog_first_file(TRANSLOG_ADDRESS horizon, int is_protected); LSN translog_next_LSN(TRANSLOG_ADDRESS addr, TRANSLOG_ADDRESS horizon); - +static void translog_free_link(PAGECACHE_BLOCK_LINK *direct_link); /* Initialize log_record_type_descriptors @@ -3116,7 +3116,10 @@ restart: PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_LEFT_UNLOCKED, NULL))) + { + translog_unlock(); DBUG_RETURN(NULL); + } } else skipped_data= 0; /* Read after skipped in buffer data */ @@ -3217,6 +3220,11 @@ restart: PAGECACHE_LOCK_READ : PAGECACHE_LOCK_LEFT_UNLOCKED), direct_link); + if (!buffer && direct_link) + { + translog_free_link(*direct_link); + *direct_link= 0; + } DBUG_PRINT("info", ("Direct link is assigned to : %p * %p", direct_link, (direct_link ? *direct_link : NULL))); @@ -3786,16 +3794,26 @@ my_bool translog_init_with_table(const char *directory, } else if (LSN_OFFSET(last_page) == 0) { - if (LSN_FILE_NO(last_page) == 1) + if (LSN_FILE_NO(last_page) == 1 || + !translog_is_file(LSN_FILE_NO(last_page-1))) { logs_found= 0; /* file #1 has no pages */ DBUG_PRINT("info", ("log found. But is is empty => no log assumed")); } else { - last_page-= LSN_ONE_FILE; - if (translog_get_last_page_addr(&last_page, &pageok, 0)) - goto err; + do + { + last_page-= LSN_ONE_FILE; + if (translog_get_last_page_addr(&last_page, &pageok, 0)) + goto err; + } + while (LSN_OFFSET(last_page) == 0 && LSN_FILE_NO(last_page) >= 1); + if (LSN_OFFSET(last_page) == 0) + { + /* All files have a size less than TRANSLOG_PAGE_SIZE */ + logs_found= 0; + } } } if (logs_found) @@ -3893,36 +3911,38 @@ my_bool translog_init_with_table(const char *directory, old_log_was_recovered= 1; /* This file is not written till the end so it should be last */ last_page= current_file_last_page; - /* TODO: issue warning */ } - do + if (LSN_OFFSET(current_file_last_page) >= TRANSLOG_PAGE_SIZE) { - TRANSLOG_VALIDATOR_DATA data; - TRANSLOG_PAGE_SIZE_BUFF psize_buff; - uchar *page; - data.addr= ¤t_page; - if ((page= translog_get_page(&data, psize_buff.buffer, NULL)) == NULL) - goto err; - if (data.was_recovered) + do { - DBUG_PRINT("error", ("file no: %lu (%d) " - "rec_offset: 0x%lx (%lu) (%d)", - (ulong) LSN_FILE_NO(current_page), - (uint3korr(page + 3) != - LSN_FILE_NO(current_page)), - (ulong) LSN_OFFSET(current_page), - (ulong) (LSN_OFFSET(current_page) / - TRANSLOG_PAGE_SIZE), - (uint3korr(page) != - LSN_OFFSET(current_page) / - TRANSLOG_PAGE_SIZE))); - old_log_was_recovered= 1; - break; - } - old_flags= page[TRANSLOG_PAGE_FLAGS]; - last_valid_page= current_page; - current_page+= TRANSLOG_PAGE_SIZE; /* increase offset */ - } while (current_page <= current_file_last_page); + TRANSLOG_VALIDATOR_DATA data; + TRANSLOG_PAGE_SIZE_BUFF psize_buff; + uchar *page; + data.addr= ¤t_page; + if ((page= translog_get_page(&data, psize_buff.buffer, NULL)) == NULL) + goto err; + if (data.was_recovered) + { + DBUG_PRINT("error", ("file no: %lu (%d) " + "rec_offset: 0x%lx (%lu) (%d)", + (ulong) LSN_FILE_NO(current_page), + (uint3korr(page + 3) != + LSN_FILE_NO(current_page)), + (ulong) LSN_OFFSET(current_page), + (ulong) (LSN_OFFSET(current_page) / + TRANSLOG_PAGE_SIZE), + (uint3korr(page) != + LSN_OFFSET(current_page) / + TRANSLOG_PAGE_SIZE))); + old_log_was_recovered= 1; + break; + } + old_flags= page[TRANSLOG_PAGE_FLAGS]; + last_valid_page= current_page; + current_page+= TRANSLOG_PAGE_SIZE; /* increase offset */ + } while (current_page <= current_file_last_page); + } current_page+= LSN_ONE_FILE; current_page= LSN_REPLACE_OFFSET(current_page, TRANSLOG_PAGE_SIZE); } while (LSN_FILE_NO(current_page) <= LSN_FILE_NO(last_page) && @@ -4014,7 +4034,7 @@ my_bool translog_init_with_table(const char *directory, } DBUG_PRINT("info", ("Logs found: %d was recovered: %d", logs_found, old_log_was_recovered)); - if (!logs_found) + if (!logs_found && !readonly) { TRANSLOG_FILE *file= (TRANSLOG_FILE*)my_malloc(PSI_INSTRUMENT_ME, sizeof(TRANSLOG_FILE), MYF(MY_WME)); @@ -4064,6 +4084,10 @@ my_bool translog_init_with_table(const char *directory, translog_start_buffer(log_descriptor.buffers, &log_descriptor.bc, 0); translog_new_page_header(&log_descriptor.horizon, &log_descriptor.bc); } + else if (readonly && !logs_found) + { + log_descriptor.horizon= LSN_IMPOSSIBLE; + } /* all LSNs that are on disk are flushed */ log_descriptor.log_start= log_descriptor.sent_to_disk= @@ -4145,21 +4169,24 @@ my_bool translog_init_with_table(const char *directory, uint32 file_no= LSN_FILE_NO(page_addr); my_bool last_page_ok; /* it is beginning of the current file */ - if (unlikely(file_no == 1)) + do { - /* - It is beginning of the log => there is no LSNs in the log => - There is no harm in leaving it "as-is". + if (unlikely(file_no == 1)) + { + /* + It is beginning of the log => there is no LSNs in the log => + There is no harm in leaving it "as-is". */ - log_descriptor.previous_flush_horizon= log_descriptor.horizon; - DBUG_PRINT("info", ("previous_flush_horizon: " LSN_FMT, - LSN_IN_PARTS(log_descriptor. + log_descriptor.previous_flush_horizon= log_descriptor.horizon; + DBUG_PRINT("info", ("previous_flush_horizon: " LSN_FMT, + LSN_IN_PARTS(log_descriptor. previous_flush_horizon))); - DBUG_RETURN(0); - } - file_no--; - page_addr= MAKE_LSN(file_no, TRANSLOG_PAGE_SIZE); - translog_get_last_page_addr(&page_addr, &last_page_ok, 0); + DBUG_RETURN(0); + } + file_no--; + page_addr= MAKE_LSN(file_no, TRANSLOG_PAGE_SIZE); + translog_get_last_page_addr(&page_addr, &last_page_ok, 0); + } while (LSN_OFFSET(page_addr) == 0); /* page should be OK as it is not the last file */ DBUG_ASSERT(last_page_ok); } @@ -6905,17 +6932,19 @@ translog_get_next_chunk(TRANSLOG_SCANNER_DATA *scanner) /* if it is log end it have to be caught before */ DBUG_ASSERT(LSN_FILE_NO(scanner->horizon) > LSN_FILE_NO(scanner->page_addr)); - scanner->page_addr+= LSN_ONE_FILE; - scanner->page_addr= LSN_REPLACE_OFFSET(scanner->page_addr, - TRANSLOG_PAGE_SIZE); - if (translog_scanner_set_last_page(scanner)) - DBUG_RETURN(1); + do + { + scanner->page_addr+= LSN_ONE_FILE; + scanner->page_addr= LSN_REPLACE_OFFSET(scanner->page_addr, + TRANSLOG_PAGE_SIZE); + if (translog_scanner_set_last_page(scanner)) + DBUG_RETURN(1); + } while (!LSN_OFFSET(scanner->last_file_page)); } else { scanner->page_addr+= TRANSLOG_PAGE_SIZE; /* offset increased */ } - if (translog_scanner_get_page(scanner)) DBUG_RETURN(1); @@ -6926,7 +6955,9 @@ translog_get_next_chunk(TRANSLOG_SCANNER_DATA *scanner) scanner->page_offset= 0; DBUG_RETURN(0); } +#ifdef CHECK_EMPTY_PAGE DBUG_ASSERT(scanner->page[scanner->page_offset] != TRANSLOG_FILLER); +#endif } DBUG_RETURN(0); } diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h index 3e5c58a8053..abe85a12727 100644 --- a/storage/maria/ma_loghandler.h +++ b/storage/maria/ma_loghandler.h @@ -25,7 +25,11 @@ /* minimum possible transaction log size */ #define TRANSLOG_MIN_FILE_SIZE (8*MB) /* transaction log default flags (TODO: make it global variable) */ +#ifdef HAVE_DBUG_TRANSLOG_CRC +#define TRANSLOG_DEFAULT_FLAGS IF_DBUG(TRANSLOG_PAGE_CRC,0) +#else #define TRANSLOG_DEFAULT_FLAGS 0 +#endif /* Transaction log flags. diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 144b10a86da..c4c85d0bdd0 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -3876,7 +3876,7 @@ restart: { pagecache_pthread_mutex_unlock(&pagecache->cache_lock); DBUG_ASSERT(0); - return (uchar*) 0; + DBUG_RETURN((uchar*) 0); } } /* @@ -5227,7 +5227,7 @@ int flush_pagecache_blocks_with_filter(PAGECACHE *pagecache, { int res; DBUG_ENTER("flush_pagecache_blocks_with_filter"); - DBUG_PRINT("enter", ("pagecache: %p", pagecache)); + DBUG_PRINT("enter", ("pagecache: %p fd: %di", pagecache, file->file)); if (pagecache->disk_blocks <= 0) DBUG_RETURN(0); diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 006c8bef672..90d0ed3c708 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -133,7 +133,7 @@ static void new_transaction(uint16 sid, TrID long_id, LSN undo_lsn, static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id); static int new_page(uint32 fileid, pgcache_page_no_t pageid, LSN rec_lsn, struct st_dirty_page *dirty_page); -static int close_all_tables(void); +static int close_all_tables(my_bool force_end_newline); static my_bool close_one_table(const char *name, TRANSLOG_ADDRESS addr); static void print_redo_phase_progress(TRANSLOG_ADDRESS addr); static void delete_all_transactions(); @@ -467,7 +467,7 @@ int maria_apply_log(LSN from_lsn, LSN end_redo_lsn, LSN end_undo_lsn, we don't use maria_panic() because it would maria_end(), and Recovery does not want that (we want to keep some modules initialized for runtime). */ - if (close_all_tables()) + if (close_all_tables(0)) { ma_message_no_user(0, "closing of tables failed"); goto err; @@ -495,6 +495,8 @@ int maria_apply_log(LSN from_lsn, LSN end_redo_lsn, LSN end_undo_lsn, /* No dirty pages, all tables are closed, no active transactions, save: */ if (ma_checkpoint_execute(CHECKPOINT_FULL, FALSE)) goto err; + tprint(tracef, "checkpoint done at " LSN_FMT "\n", + LSN_IN_PARTS(last_checkpoint_lsn)); } goto end; @@ -505,7 +507,7 @@ err2: delete_all_transactions(); if (!abort_message_printed) error= 1; - if (close_all_tables()) + if (close_all_tables(1)) { ma_message_no_user(0, "closing of tables failed"); } @@ -3472,7 +3474,7 @@ static int new_page(uint32 fileid, pgcache_page_no_t pageid, LSN rec_lsn, } -static int close_all_tables(void) +static int close_all_tables(my_bool force_end_newline) { int error= 0; uint count= 0; @@ -3537,7 +3539,7 @@ static int close_all_tables(void) } } end: - if (recovery_message_printed == REC_MSG_FLUSH) + if (recovery_message_printed == REC_MSG_FLUSH && (force_end_newline || error)) { fputc('\n', stderr); fflush(stderr); diff --git a/storage/maria/ma_recovery_util.c b/storage/maria/ma_recovery_util.c index fe43d812600..b8123c422c1 100644 --- a/storage/maria/ma_recovery_util.c +++ b/storage/maria/ma_recovery_util.c @@ -87,7 +87,7 @@ void eprint(FILE *trace_file __attribute__ ((unused)), if (!trace_file) trace_file= stderr; - if (procent_printed) + if (procent_printed && trace_file == stderr) { procent_printed= 0; /* In silent mode, print on another line than the 0% 10% 20% line */ diff --git a/storage/maria/ma_rkey.c b/storage/maria/ma_rkey.c index 8cd82e1c6fc..7e43ed4befa 100644 --- a/storage/maria/ma_rkey.c +++ b/storage/maria/ma_rkey.c @@ -120,6 +120,7 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data, /* The key references a concurrently inserted record. */ if (search_flag == HA_READ_KEY_EXACT && + (keyinfo->flag & HA_NOSAME) && last_used_keyseg == keyinfo->seg + keyinfo->keysegs) { /* Simply ignore the key if it matches exactly. (Bug #29838) */ diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index c7aef97072b..f17edfe0657 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -213,7 +213,6 @@ extern int maria_rsame_with_pos(MARIA_HA *file, uchar *record, extern int maria_update(MARIA_HA *file, const uchar *old, const uchar *new_record); extern int maria_write(MARIA_HA *file, const uchar *buff); -extern MARIA_RECORD_POS maria_position(MARIA_HA *file); extern int maria_status(MARIA_HA *info, MARIA_INFO *x, uint flag); extern int maria_lock_database(MARIA_HA *file, int lock_type); extern int maria_delete_table(const char *name); @@ -1011,6 +1010,7 @@ struct st_maria_handler my_bool switched_transactional; /* If transaction will autocommit */ my_bool autocommit; + my_bool has_cond_pushdown; #ifdef _WIN32 my_bool owned_by_merge; /* This Maria table is part of a merge union */ #endif @@ -1022,6 +1022,8 @@ struct st_maria_handler my_bool create_unique_index_by_sort; index_cond_func_t index_cond_func; /* Index condition function */ void *index_cond_func_arg; /* parameter for the func */ + rowid_filter_func_t rowid_filter_func; /* rowid filter check function */ + void *rowid_filter_func_arg; /* parameter for the func */ }; /* Table options for the Aria and S3 storage engine */ @@ -1063,6 +1065,7 @@ struct ha_table_option_struct #define STATE_IN_REPAIR 1024U /* We are running repair on table */ #define STATE_CRASHED_PRINTED 2048U #define STATE_DATA_FILE_FULL 4096U +#define STATE_HAS_LSN 8192U /* Some page still has LSN */ #define STATE_CRASHED_FLAGS (STATE_CRASHED | STATE_CRASHED_ON_REPAIR | STATE_CRASHED_PRINTED) @@ -1346,7 +1349,11 @@ extern int _ma_read_rnd_no_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos, my_bool skip_deleted_blocks); my_off_t _ma_no_keypos_to_recpos(MARIA_SHARE *share, my_off_t pos); - +/* Get position to last record */ +static inline MARIA_RECORD_POS maria_position(MARIA_HA *info) +{ + return info->cur_row.lastpos; +} extern my_bool _ma_ck_write(MARIA_HA *info, MARIA_KEY *key); extern my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key, MARIA_RECORD_POS *root); @@ -1733,7 +1740,25 @@ extern my_bool maria_flush_log_for_page_none(PAGECACHE_IO_HOOK_ARGS *args); extern PAGECACHE *maria_log_pagecache; extern void ma_set_index_cond_func(MARIA_HA *info, index_cond_func_t func, void *func_arg); -check_result_t ma_check_index_cond(MARIA_HA *info, uint keynr, uchar *record); +extern void ma_set_rowid_filter_func(MARIA_HA *info, + rowid_filter_func_t check_func, + void *func_arg); +static inline void ma_reset_index_filter_functions(MARIA_HA *info) +{ + info->index_cond_func= NULL; + info->rowid_filter_func= NULL; + info->has_cond_pushdown= 0; +} +check_result_t ma_check_index_cond_real(MARIA_HA *info, uint keynr, + uchar *record); +static inline check_result_t ma_check_index_cond(MARIA_HA *info, uint keynr, + uchar *record) +{ + if (!info->has_cond_pushdown) + return CHECK_POS; + return ma_check_index_cond_real(info, keynr, record); +} + extern my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx); extern my_bool ma_killed_standalone(MARIA_HA *); diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 7787f8b83b5..85d6473ded3 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -4308,6 +4308,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint open_options) wrap_handler->set_ha_share_ref(&table->s->ha_share); #endif error = wrap_handler->ha_open(table, name, mode, open_options); + wrap_handler->set_optimizer_costs(ha_thd()); } else { if (!(wrap_handler = parent_for_clone->wrap_handler->clone(name, mem_root_for_clone))) @@ -12313,6 +12314,7 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno, uint n_ranges, uint *bufsz, uint *flags, + ha_rows limit, Cost_estimate *cost) { MRN_DBUG_ENTER_METHOD(); @@ -12320,7 +12322,8 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno, KEY *key_info = &(table->key_info[keyno]); if (mrn_is_geo_key(key_info)) { rows = handler::multi_range_read_info_const(keyno, seq, seq_init_param, - n_ranges, bufsz, flags, cost); + n_ranges, bufsz, flags, limit, + cost); DBUG_RETURN(rows); } MRN_SET_WRAP_SHARE_KEY(share, table->s); @@ -12329,7 +12332,7 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno, set_pk_bitmap(); rows = wrap_handler->multi_range_read_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, flags, - cost); + limit, cost); MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); DBUG_RETURN(rows); @@ -12341,20 +12344,21 @@ ha_rows ha_mroonga::storage_multi_range_read_info_const(uint keyno, uint n_ranges, uint *bufsz, uint *flags, + ha_rows limit, Cost_estimate *cost) { MRN_DBUG_ENTER_METHOD(); ha_rows rows = handler::multi_range_read_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, flags, - cost); + limit, cost); DBUG_RETURN(rows); } ha_rows ha_mroonga::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, + uint *flags, ha_rows limit, Cost_estimate *cost) { MRN_DBUG_ENTER_METHOD(); @@ -12363,11 +12367,11 @@ ha_rows ha_mroonga::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, { rows = wrapper_multi_range_read_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, - flags, cost); + flags, limit, cost); } else { rows = storage_multi_range_read_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, - flags, cost); + flags, limit, cost); } DBUG_RETURN(rows); } @@ -13008,9 +13012,9 @@ int ha_mroonga::truncate() DBUG_RETURN(error); } -double ha_mroonga::wrapper_scan_time() +IO_AND_CPU_COST ha_mroonga::wrapper_scan_time() { - double res; + IO_AND_CPU_COST res; MRN_DBUG_ENTER_METHOD(); MRN_SET_WRAP_SHARE_KEY(share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); @@ -13020,17 +13024,16 @@ double ha_mroonga::wrapper_scan_time() DBUG_RETURN(res); } -double ha_mroonga::storage_scan_time() +IO_AND_CPU_COST ha_mroonga::storage_scan_time() { MRN_DBUG_ENTER_METHOD(); - double time = handler::scan_time(); - DBUG_RETURN(time); + DBUG_RETURN(handler::scan_time()); } -double ha_mroonga::scan_time() +IO_AND_CPU_COST ha_mroonga::scan_time() { MRN_DBUG_ENTER_METHOD(); - double time; + IO_AND_CPU_COST time; if (share->wrapper_mode) { time = wrapper_scan_time(); @@ -13040,51 +13043,87 @@ double ha_mroonga::scan_time() DBUG_RETURN(time); } -double ha_mroonga::wrapper_read_time(uint index, uint ranges, ha_rows rows) +IO_AND_CPU_COST ha_mroonga::wrapper_rnd_pos_time(ha_rows rows) { - double res; + IO_AND_CPU_COST res; + MRN_DBUG_ENTER_METHOD(); + MRN_SET_WRAP_SHARE_KEY(share, table->s); + MRN_SET_WRAP_TABLE_KEY(this, table); + res = wrap_handler->rnd_pos_time(rows); + MRN_SET_BASE_SHARE_KEY(share, table->s); + MRN_SET_BASE_TABLE_KEY(this, table); + DBUG_RETURN(res); +} + +IO_AND_CPU_COST ha_mroonga::storage_rnd_pos_time(ha_rows rows) +{ + MRN_DBUG_ENTER_METHOD(); + IO_AND_CPU_COST time = handler::rnd_pos_time(rows); + DBUG_RETURN(time); +} + + +IO_AND_CPU_COST ha_mroonga::rnd_pos_time(ha_rows rows) +{ + MRN_DBUG_ENTER_METHOD(); + IO_AND_CPU_COST time; + if (share->wrapper_mode) + { + time = wrapper_rnd_pos_time(rows); + } else { + time = storage_rnd_pos_time(rows); + } + DBUG_RETURN(time); +} + + +IO_AND_CPU_COST ha_mroonga::wrapper_keyread_time(uint index, ulong ranges, + ha_rows rows, ulonglong blocks) +{ + IO_AND_CPU_COST res; MRN_DBUG_ENTER_METHOD(); if (index < MAX_KEY) { KEY *key_info = &(table->key_info[index]); if (mrn_is_geo_key(key_info)) { - res = handler::read_time(index, ranges, rows); + res = handler::keyread_time(index, ranges, rows, blocks); DBUG_RETURN(res); } MRN_SET_WRAP_SHARE_KEY(share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); - res = wrap_handler->read_time(share->wrap_key_nr[index], ranges, rows); + res = wrap_handler->keyread_time(share->wrap_key_nr[index], ranges, rows, blocks); MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); } else { MRN_SET_WRAP_SHARE_KEY(share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); - res = wrap_handler->read_time(index, ranges, rows); + res = wrap_handler->keyread_time(index, ranges, rows, blocks); MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); } DBUG_RETURN(res); } -double ha_mroonga::storage_read_time(uint index, uint ranges, ha_rows rows) +IO_AND_CPU_COST ha_mroonga::storage_keyread_time(uint index, ulong ranges, ha_rows rows, ulonglong blocks) { MRN_DBUG_ENTER_METHOD(); - double time = handler::read_time(index, ranges, rows); + IO_AND_CPU_COST time = handler::keyread_time(index, ranges, rows, blocks); DBUG_RETURN(time); } -double ha_mroonga::read_time(uint index, uint ranges, ha_rows rows) +IO_AND_CPU_COST ha_mroonga::keyread_time(uint index, ulong ranges, ha_rows rows, ulonglong blocks) { MRN_DBUG_ENTER_METHOD(); - double time; + IO_AND_CPU_COST time; if (share->wrapper_mode) { - time = wrapper_read_time(index, ranges, rows); + time = wrapper_keyread_time(index, ranges, rows, blocks); } else { - time = storage_read_time(index, ranges, rows); + time = storage_keyread_time(index, ranges, rows, blocks); } DBUG_RETURN(time); } + #ifdef MRN_HANDLER_HAVE_KEYS_TO_USE_FOR_SCANNING const key_map *ha_mroonga::wrapper_keys_to_use_for_scanning() { diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp index 66767899e21..27219ffd158 100644 --- a/storage/mroonga/ha_mroonga.hpp +++ b/storage/mroonga/ha_mroonga.hpp @@ -505,7 +505,8 @@ public: ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost) mrn_override; + uint *flags, ha_rows limit, + Cost_estimate *cost) mrn_override; ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, #ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS uint key_parts, @@ -531,8 +532,9 @@ public: int end_bulk_insert() mrn_override; int delete_all_rows() mrn_override; int truncate() mrn_override; - double scan_time() mrn_override; - double read_time(uint index, uint ranges, ha_rows rows) mrn_override; + IO_AND_CPU_COST scan_time() mrn_override; + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) mrn_override; + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, ulonglong blocks) mrn_override; #ifdef MRN_HANDLER_HAVE_KEYS_TO_USE_FOR_SCANNING const key_map *keys_to_use_for_scanning() mrn_override; #endif @@ -1056,6 +1058,7 @@ private: uint n_ranges, uint *bufsz, uint *flags, + ha_rows limit, Cost_estimate *cost); ha_rows storage_multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, @@ -1063,6 +1066,7 @@ private: uint n_ranges, uint *bufsz, uint *flags, + ha_rows limit, Cost_estimate *cost); ha_rows wrapper_multi_range_read_info(uint keyno, uint n_ranges, uint keys, #ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS @@ -1106,10 +1110,12 @@ private: int wrapper_truncate_index(); int storage_truncate(); int storage_truncate_index(); - double wrapper_scan_time(); - double storage_scan_time(); - double wrapper_read_time(uint index, uint ranges, ha_rows rows); - double storage_read_time(uint index, uint ranges, ha_rows rows); + IO_AND_CPU_COST wrapper_scan_time(); + IO_AND_CPU_COST storage_scan_time(); + IO_AND_CPU_COST wrapper_rnd_pos_time(ha_rows rows); + IO_AND_CPU_COST storage_rnd_pos_time(ha_rows rows); + IO_AND_CPU_COST wrapper_keyread_time(uint index, ulong ranges, ha_rows rows, ulonglong blocks); + IO_AND_CPU_COST storage_keyread_time(uint index, ulong ranges, ha_rows rows, ulonglong blocks); #ifdef MRN_HANDLER_HAVE_KEYS_TO_USE_FOR_SCANNING const key_map *wrapper_keys_to_use_for_scanning(); const key_map *storage_keys_to_use_for_scanning(); diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_not_equal.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_not_equal.result index a1a123e7d5f..837ca2b6381 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_not_equal.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_index_not_equal.result @@ -9,6 +9,9 @@ INSERT INTO users (age) VALUES (28); INSERT INTO users (age) VALUES (29); INSERT INTO users (age) VALUES (29); INSERT INTO users (age) VALUES (29); +explain SELECT COUNT(*) FROM users WHERE age <> 29; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE users range age age 5 NULL 4 Using where; Using index SELECT COUNT(*) FROM users WHERE age <> 29; COUNT(*) 2 diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_not_equal.test b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_not_equal.test index 3948d218a69..7e6cf5f510b 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_not_equal.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/optimization_count_skip_index_not_equal.test @@ -33,6 +33,7 @@ INSERT INTO users (age) VALUES (29); INSERT INTO users (age) VALUES (29); INSERT INTO users (age) VALUES (29); +explain SELECT COUNT(*) FROM users WHERE age <> 29; SELECT COUNT(*) FROM users WHERE age <> 29; SHOW STATUS LIKE 'mroonga_count_skip'; diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result index 550554eac8c..6dd6dd25f3f 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/geometry_contains.result @@ -154,7 +154,7 @@ id name location_text select id, name, ST_AsText(location) as location_text from shops where MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location); id name location_text +26 kazuya POINT(139.760895 35.673508) 14 tetsuji POINT(139.76857 35.680912) 19 daruma POINT(139.770599 35.681461) -26 kazuya POINT(139.760895 35.673508) drop table shops; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index a1de9edd997..b1b1e8fd57e 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -804,6 +804,17 @@ ulong ha_myisam::index_flags(uint inx, uint part, bool all_parts) const return flags; } +IO_AND_CPU_COST ha_myisam::rnd_pos_time(ha_rows rows) +{ + IO_AND_CPU_COST cost= handler::rnd_pos_time(rows); + /* + Row data is not cached. costs.row_lookup_cost includes the cost of + the reading the row from system (probably cached by the OS). + */ + cost.io= 0; + return cost; +} + /* Name is here without an extension */ int ha_myisam::open(const char *name, int mode, uint test_if_locked) @@ -1960,9 +1971,8 @@ int ha_myisam::index_init(uint idx, bool sorted) active_index=idx; if (pushed_idx_cond_keyno == idx) mi_set_index_cond_func(file, handler_index_cond_check, this); - if (pushed_rowid_filter) - mi_set_rowid_filter_func(file, handler_rowid_filter_check, - handler_rowid_filter_is_active, this); + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + mi_set_rowid_filter_func(file, handler_rowid_filter_check, this); return 0; } @@ -1970,11 +1980,10 @@ int ha_myisam::index_init(uint idx, bool sorted) int ha_myisam::index_end() { DBUG_ENTER("ha_myisam::index_end"); - active_index=MAX_KEY; - //pushed_idx_cond_keyno= MAX_KEY; + active_index= MAX_KEY; mi_set_index_cond_func(file, NULL, 0); in_range_check_pushed_down= FALSE; - mi_set_rowid_filter_func(file, NULL, NULL, 0); + mi_set_rowid_filter_func(file, NULL, 0); ds_mrr.dsmrr_close(); #if !defined(DBUG_OFF) && defined(SQL_SELECT_FIXED_FOR_UPDATE) file->update&= ~HA_STATE_AKTIV; // Forget active row @@ -2010,9 +2019,8 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key, end_range= NULL; if (index == pushed_idx_cond_keyno) mi_set_index_cond_func(file, handler_index_cond_check, this); - if (pushed_rowid_filter) - mi_set_rowid_filter_func(file, handler_rowid_filter_check, - handler_rowid_filter_is_active, this); + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + mi_set_rowid_filter_func(file, handler_rowid_filter_check, this); res= mi_rkey(file, buf, index, key, keypart_map, find_flag); mi_set_index_cond_func(file, NULL, 0); return res; @@ -2144,9 +2152,17 @@ int ha_myisam::info(uint flag) share->keys_for_keyread.intersect(share->keys_in_use); share->db_record_offset= misam_info.record_offset; if (share->key_parts) - memcpy((char*) table->key_info[0].rec_per_key, - (char*) misam_info.rec_per_key, - sizeof(table->key_info[0].rec_per_key[0])*share->key_parts); + { + ulong *from= misam_info.rec_per_key; + KEY *key, *key_end; + for (key= table->key_info, key_end= key + share->keys; + key < key_end ; key++) + { + memcpy(key->rec_per_key, from, + key->user_defined_key_parts * sizeof(*from)); + from+= key->user_defined_key_parts; + } + } if (table_share->tmp_table == NO_TMP_TABLE) mysql_mutex_unlock(&table_share->LOCK_share); } @@ -2577,6 +2593,22 @@ static int myisam_drop_table(handlerton *hton, const char *path) return mi_delete_table(path); } + +void myisam_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + /* + MyISAM row lookup costs are slow as the row data is not cached + The following numbers where found by check_costs.pl when using 1M rows + and all rows are cached. See optimizer_costs.txt + */ + costs->row_next_find_cost= 0.000063539; + costs->row_lookup_cost= 0.001014818; + costs->key_next_find_cost= 0.000090585; + costs->key_lookup_cost= 0.000550142; + costs->key_copy_cost= 0.000015685; +} + + static int myisam_init(void *p) { handlerton *hton; @@ -2596,6 +2628,7 @@ static int myisam_init(void *p) hton->create= myisam_create_handler; hton->drop_table= myisam_drop_table; hton->panic= myisam_panic; + hton->update_optimizer_costs= myisam_update_optimizer_costs; hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES; hton->tablefile_extensions= ha_myisam_exts; mi_killed= mi_killed_in_mariadb; @@ -2635,7 +2668,8 @@ int ha_myisam::multi_range_read_next(range_id_t *range_info) ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost) + uint *flags, ha_rows limit, + Cost_estimate *cost) { /* This call is here because there is no location where this->table would @@ -2644,7 +2678,7 @@ ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, */ ds_mrr.init(this, table); return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, - flags, cost); + flags, limit, cost); } ha_rows ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys, @@ -2699,12 +2733,23 @@ Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) bool ha_myisam::rowid_filter_push(Rowid_filter* rowid_filter) { + /* This will be used in index_init() */ pushed_rowid_filter= rowid_filter; - mi_set_rowid_filter_func(file, handler_rowid_filter_check, - handler_rowid_filter_is_active, this); return false; } + +/* Enable / disable rowid filter depending if it's active or not */ + +void ha_myisam::rowid_filter_changed() +{ + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + mi_set_rowid_filter_func(file, handler_rowid_filter_check, this); + else + mi_set_rowid_filter_func(file, NULL, this); +} + + struct st_mysql_storage_engine myisam_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 3843004cc6e..68ad636c48e 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -54,125 +54,132 @@ class ha_myisam final : public handler public: ha_myisam(handlerton *hton, TABLE_SHARE *table_arg); ~ha_myisam() {} - handler *clone(const char *name, MEM_ROOT *mem_root); - const char *index_type(uint key_number); - ulonglong table_flags() const { return int_table_flags; } - int index_init(uint idx, bool sorted); - int index_end(); - int rnd_end(); + handler *clone(const char *name, MEM_ROOT *mem_root) override; + const char *index_type(uint key_number) override; + ulonglong table_flags() const override { return int_table_flags; } + int index_init(uint idx, bool sorted) override; + int index_end() override; + int rnd_end() override; - ulong index_flags(uint inx, uint part, bool all_parts) const; - uint max_supported_keys() const { return MI_MAX_KEY; } - uint max_supported_key_parts() const { return HA_MAX_KEY_SEG; } - uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; } - uint max_supported_key_part_length() const { return HA_MAX_KEY_LENGTH; } - void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share); - int open(const char *name, int mode, uint test_if_locked); - int close(void); - int write_row(const uchar * buf); - int update_row(const uchar * old_data, const uchar * new_data); - int delete_row(const uchar * buf); + ulong index_flags(uint inx, uint part, bool all_parts) const override; + uint max_supported_keys() const override { return MI_MAX_KEY; } + uint max_supported_key_parts() const override { return HA_MAX_KEY_SEG; } + uint max_supported_key_length() const override { return HA_MAX_KEY_LENGTH; } + uint max_supported_key_part_length() const override + { return HA_MAX_KEY_LENGTH; } + void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) override; + int open(const char *name, int mode, uint test_if_locked) override; + int close(void) override; + int write_row(const uchar * buf) override; + int update_row(const uchar * old_data, const uchar * new_data) override; + int delete_row(const uchar * buf) override; int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, - enum ha_rkey_function find_flag); + enum ha_rkey_function find_flag) override; int index_read_idx_map(uchar *buf, uint index, const uchar *key, key_part_map keypart_map, - enum ha_rkey_function find_flag); - int index_next(uchar * buf); - int index_prev(uchar * buf); - int index_first(uchar * buf); - int index_last(uchar * buf); - int index_next_same(uchar *buf, const uchar *key, uint keylen); - int ft_init() + enum ha_rkey_function find_flag) override; + int index_next(uchar * buf) override; + int index_prev(uchar * buf) override; + int index_first(uchar * buf) override; + int index_last(uchar * buf) override; + int index_next_same(uchar *buf, const uchar *key, uint keylen) override; + int ft_init() override { if (!ft_handler) return 1; ft_handler->please->reinit_search(ft_handler); return 0; } - FT_INFO *ft_init_ext(uint flags, uint inx,String *key) + FT_INFO *ft_init_ext(uint flags, uint inx,String *key) override { return ft_init_search(flags,file,inx, (uchar *)key->ptr(), key->length(), key->charset(), table->record[0]); } - int ft_read(uchar *buf); - int rnd_init(bool scan); - int rnd_next(uchar *buf); - int rnd_pos(uchar * buf, uchar *pos); - int remember_rnd_pos(); - int restart_rnd_next(uchar *buf); - void position(const uchar *record); - int info(uint); - int extra(enum ha_extra_function operation); - int extra_opt(enum ha_extra_function operation, ulong cache_size); - int reset(void); - int external_lock(THD *thd, int lock_type); - int delete_all_rows(void); - int reset_auto_increment(ulonglong value); - int disable_indexes(uint mode); - int enable_indexes(uint mode); - int indexes_are_disabled(void); - void start_bulk_insert(ha_rows rows, uint flags); - int end_bulk_insert(); + int ft_read(uchar *buf) override; + int rnd_init(bool scan) override; + int rnd_next(uchar *buf) override; + int rnd_pos(uchar * buf, uchar *pos) override; + int remember_rnd_pos() override; + int restart_rnd_next(uchar *buf) override; + void position(const uchar *record) override; + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) override; + int info(uint) override; + int extra(enum ha_extra_function operation) override; + int extra_opt(enum ha_extra_function operation, ulong cache_size) override; + int reset(void) override; + int external_lock(THD *thd, int lock_type) override; + int delete_all_rows(void) override; + int reset_auto_increment(ulonglong value) override; + int disable_indexes(uint mode) override; + int enable_indexes(uint mode) override; + int indexes_are_disabled(void) override; + void start_bulk_insert(ha_rows rows, uint flags) override; + int end_bulk_insert() override; ha_rows records_in_range(uint inx, const key_range *min_key, - const key_range *max_key, page_range *pages); - void update_create_info(HA_CREATE_INFO *create_info); - int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); + const key_range *max_key, page_range *pages) override; + void update_create_info(HA_CREATE_INFO *create_info) override; + int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info) override; THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, - enum thr_lock_type lock_type); - virtual void get_auto_increment(ulonglong offset, ulonglong increment, - ulonglong nb_desired_values, - ulonglong *first_value, - ulonglong *nb_reserved_values); - int rename_table(const char * from, const char * to); - int delete_table(const char *name); - int check_for_upgrade(HA_CHECK_OPT *check_opt); - int check(THD* thd, HA_CHECK_OPT* check_opt); - int analyze(THD* thd,HA_CHECK_OPT* check_opt); - int repair(THD* thd, HA_CHECK_OPT* check_opt); - bool check_and_repair(THD *thd); - bool is_crashed() const; - bool auto_repair(int error) const + enum thr_lock_type lock_type) override; + void get_auto_increment(ulonglong offset, ulonglong increment, + ulonglong nb_desired_values, + ulonglong *first_value, + ulonglong *nb_reserved_values) override; + int rename_table(const char * from, const char * to) override; + int delete_table(const char *name) override; + int check_for_upgrade(HA_CHECK_OPT *check_opt) override; + int check(THD* thd, HA_CHECK_OPT* check_opt) override; + int analyze(THD* thd,HA_CHECK_OPT* check_opt) override; + int repair(THD* thd, HA_CHECK_OPT* check_opt) override; + bool check_and_repair(THD *thd) override; + bool is_crashed() const override; + bool auto_repair(int error) const override { return (myisam_recover_options != HA_RECOVER_OFF && error == HA_ERR_CRASHED_ON_USAGE); } - int optimize(THD* thd, HA_CHECK_OPT* check_opt); - int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt); - int preload_keys(THD* thd, HA_CHECK_OPT* check_opt); + int optimize(THD* thd, HA_CHECK_OPT* check_opt) override; + int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) override; + int preload_keys(THD* thd, HA_CHECK_OPT* check_opt) override; enum_alter_inplace_result check_if_supported_inplace_alter(TABLE *new_table, - Alter_inplace_info *alter_info); - bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); + Alter_inplace_info *alter_info) + override; + bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes) + override; #ifdef HAVE_QUERY_CACHE my_bool register_query_cache_table(THD *thd, const char *table_key, uint key_length, qc_engine_callback *engine_callback, - ulonglong *engine_data); + ulonglong *engine_data) override; #endif - MI_INFO *file_ptr(void) - { - return file; - } -public: /** * Multi Range Read interface */ int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, - uint n_ranges, uint mode, HANDLER_BUFFER *buf); - int multi_range_read_next(range_id_t *range_info); + uint n_ranges, uint mode, HANDLER_BUFFER *buf) override; + int multi_range_read_next(range_id_t *range_info) override; ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost); + uint *flags, ha_rows limit, + Cost_estimate *cost) override; ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, uint key_parts, uint *bufsz, - uint *flags, Cost_estimate *cost); - int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size); + uint *flags, Cost_estimate *cost) override; + int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size) override; /* Index condition pushdown implementation */ - Item *idx_cond_push(uint keyno, Item* idx_cond); - bool rowid_filter_push(Rowid_filter* rowid_filter); + Item *idx_cond_push(uint keyno, Item* idx_cond) override; + bool rowid_filter_push(Rowid_filter* rowid_filter) override; + void rowid_filter_changed() override; + + /* Used by myisammrg */ + MI_INFO *file_ptr(void) + { + return file; + } private: DsMrr_impl ds_mrr; diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index 66238745a04..e7e64edd926 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -376,16 +376,16 @@ void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t func, { info->index_cond_func= func; info->index_cond_func_arg= func_arg; + info->has_cond_pushdown= (info->index_cond_func || info->rowid_filter_func); } void mi_set_rowid_filter_func(MI_INFO *info, rowid_filter_func_t check_func, - rowid_filter_is_active_func_t is_active_func, void *func_arg) { info->rowid_filter_func= check_func; - info->rowid_filter_is_active_func= is_active_func; info->rowid_filter_func_arg= func_arg; + info->has_cond_pushdown= (info->index_cond_func || info->rowid_filter_func); } /* diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c index 087eb59c7c0..bde3ee19e2c 100644 --- a/storage/myisam/mi_key.c +++ b/storage/myisam/mi_key.c @@ -510,14 +510,6 @@ int mi_unpack_index_tuple(MI_INFO *info, uint keynr, uchar *record) } -static int mi_check_rowid_filter_is_active(MI_INFO *info) -{ - if (info->rowid_filter_is_active_func == NULL) - return 0; - return info->rowid_filter_is_active_func(info->rowid_filter_func_arg); -} - - /* Check the current index tuple: Check ICP condition and/or Rowid Filter @@ -532,21 +524,23 @@ static int mi_check_rowid_filter_is_active(MI_INFO *info) Check result according to check_result_t definition */ -check_result_t mi_check_index_tuple(MI_INFO *info, uint keynr, uchar *record) +check_result_t mi_check_index_tuple_real(MI_INFO *info, uint keynr, uchar *record) { - int need_unpack= TRUE; check_result_t res= CHECK_POS; + DBUG_ASSERT(info->index_cond_func || info->rowid_filter_func); + + if (mi_unpack_index_tuple(info, keynr, record)) + return CHECK_ERROR; if (info->index_cond_func) { - if (mi_unpack_index_tuple(info, keynr, record)) - res= CHECK_ERROR; - else if ((res= info->index_cond_func(info->index_cond_func_arg)) == - CHECK_OUT_OF_RANGE) + if ((res= info->index_cond_func(info->index_cond_func_arg)) == + CHECK_OUT_OF_RANGE) { /* We got beyond the end of scanned range */ info->lastpos= HA_OFFSET_ERROR; /* No active record */ my_errno= HA_ERR_END_OF_FILE; + return res; } /* @@ -555,25 +549,17 @@ check_result_t mi_check_index_tuple(MI_INFO *info, uint keynr, uchar *record) */ if (res != CHECK_POS) return res; - - need_unpack= FALSE; } /* Check the Rowid Filter, if present */ - if (mi_check_rowid_filter_is_active(info)) + if (info->rowid_filter_func) { - /* Unpack the index tuple if we haven't done it already */ - if (need_unpack && mi_unpack_index_tuple(info, keynr, record)) - res= CHECK_ERROR; - else + if ((res= info->rowid_filter_func(info->rowid_filter_func_arg)) == + CHECK_OUT_OF_RANGE) { - if ((res= info->rowid_filter_func(info->rowid_filter_func_arg)) == - CHECK_OUT_OF_RANGE) - { - /* We got beyond the end of scanned range */ - info->lastpos= HA_OFFSET_ERROR; /* No active record */ - my_errno= HA_ERR_END_OF_FILE; - } + /* We got beyond the end of scanned range */ + info->lastpos= HA_OFFSET_ERROR; /* No active record */ + my_errno= HA_ERR_END_OF_FILE; } } return res; diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c index bf6f3ef852c..590981fb790 100644 --- a/storage/myisam/mi_rkey.c +++ b/storage/myisam/mi_rkey.c @@ -119,7 +119,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, while ((info->lastpos >= info->state->data_file_length && (search_flag != HA_READ_KEY_EXACT || last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) || - (res= mi_check_index_tuple(info, inx, buf)) == CHECK_NEG) + (res= mi_check_index_tuple(info, inx, buf)) == CHECK_NEG) { uint not_used[2]; /* diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index c90d989c975..5ede6a6159c 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -304,10 +304,10 @@ struct st_myisam_info /* If info->buff has to be reread for rnext */ my_bool buff_used; my_bool create_unique_index_by_sort; + my_bool has_cond_pushdown; index_cond_func_t index_cond_func; /* Index condition function */ void *index_cond_func_arg; /* parameter for the func */ rowid_filter_func_t rowid_filter_func; /* rowid filter check function */ - rowid_filter_is_active_func_t rowid_filter_is_active_func; /* is activefunction */ void *rowid_filter_func_arg; /* parameter for the func */ THR_LOCK_DATA lock; uchar *rtree_recursion_state; /* For RTREE */ @@ -742,7 +742,15 @@ my_bool mi_dynmap_file(MI_INFO *info, my_off_t size); int mi_munmap_file(MI_INFO *info); void mi_remap_file(MI_INFO *info, my_off_t size); -check_result_t mi_check_index_tuple(MI_INFO *info, uint keynr, uchar *record); +check_result_t mi_check_index_tuple_real(MI_INFO *info, uint keynr, + uchar *record); +static inline check_result_t mi_check_index_tuple(MI_INFO *info, uint keynr, + uchar *record) +{ + if (!info->has_cond_pushdown && ! info->rowid_filter_func) + return CHECK_POS; + return mi_check_index_tuple_real(info, keynr, record); +} /* Functions needed by mi_check */ int killed_ptr(HA_CHECK *param); @@ -754,7 +762,6 @@ extern void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t check_func, void *func_arg); extern void mi_set_rowid_filter_func(MI_INFO *info, rowid_filter_func_t check_func, - rowid_filter_is_active_func_t is_active_func, void *func_arg); int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file, ulonglong *dirty_part_map); diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index d37636abab7..ee5d44b5d26 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -339,6 +339,33 @@ static void myrg_set_external_ref(MYRG_INFO *m_info, void *ext_ref_arg) } } +IO_AND_CPU_COST ha_myisammrg::rnd_pos_time(ha_rows rows) +{ + IO_AND_CPU_COST cost= handler::rnd_pos_time(rows); + /* + Row data is notcached. costs.row_lookup_cost includes the cost of + the reading the row from system (probably cached by the OS). + */ + cost.io= 0; + return cost; +} + +IO_AND_CPU_COST ha_myisammrg::keyread_time(uint index, ulong ranges, + ha_rows rows, + ulonglong blocks) +{ + IO_AND_CPU_COST cost= handler::keyread_time(index, ranges, rows, blocks); + if (!blocks) + { + cost.io*= file->tables; + cost.cpu*= file->tables; + } + /* Add the cost of having to do a key lookup in all trees */ + if (file->tables) + cost.cpu+= (file->tables-1) * (ranges * KEY_LOOKUP_COST); + return cost; +} + /** Open a MERGE parent table, but not its children. @@ -1744,6 +1771,12 @@ int myisammrg_panic(handlerton *hton, ha_panic_function flag) return myrg_panic(flag); } +static void myisammrg_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + myisam_update_optimizer_costs(costs); +} + + static int myisammrg_init(void *p) { handlerton *myisammrg_hton; @@ -1759,7 +1792,7 @@ static int myisammrg_init(void *p) myisammrg_hton->panic= myisammrg_panic; myisammrg_hton->flags= HTON_NO_PARTITION; myisammrg_hton->tablefile_extensions= ha_myisammrg_exts; - + myisammrg_hton->update_optimizer_costs= myisammrg_update_optimizer_costs; return 0; } diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 6da327ec84b..0435f7d6bd6 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -82,8 +82,8 @@ public: ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg); ~ha_myisammrg(); - const char *index_type(uint key_number); - ulonglong table_flags() const + const char *index_type(uint key_number) override; + ulonglong table_flags() const override { return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_NO_TRANSACTIONS | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | @@ -93,70 +93,81 @@ public: HA_NO_COPY_ON_ALTER | HA_DUPLICATE_POS | HA_CAN_MULTISTEP_MERGE); } - ulong index_flags(uint inx, uint part, bool all_parts) const + ulong index_flags(uint inx, uint part, bool all_parts) const override { return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ? 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE | HA_READ_ORDER | HA_KEYREAD_ONLY); } - uint max_supported_keys() const { return MI_MAX_KEY; } - uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; } - uint max_supported_key_part_length() const { return HA_MAX_KEY_LENGTH; } - double scan_time() - { return ulonglong2double(stats.data_file_length) / IO_SIZE + file->tables; } - - int open(const char *name, int mode, uint test_if_locked); - int add_children_list(void); - int attach_children(void); - int detach_children(void); - virtual handler *clone(const char *name, MEM_ROOT *mem_root); - int close(void); - int write_row(const uchar * buf); - int update_row(const uchar * old_data, const uchar * new_data); - int delete_row(const uchar * buf); + uint max_supported_keys() const override { return MI_MAX_KEY; } + uint max_supported_key_length() const override { return HA_MAX_KEY_LENGTH; } + uint max_supported_key_part_length() const override + { return HA_MAX_KEY_LENGTH; } + IO_AND_CPU_COST scan_time() override + { + IO_AND_CPU_COST cost; + cost.io= (ulonglong2double(stats.data_file_length) / IO_SIZE + + file->tables), + cost.cpu= records() * ROW_NEXT_FIND_COST; + return cost; + } + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) override; + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) override; + int open(const char *name, int mode, uint test_if_locked) override; + handler *clone(const char *name, MEM_ROOT *mem_root) override; + int close(void) override; + int write_row(const uchar * buf) override; + int update_row(const uchar * old_data, const uchar * new_data) override; + int delete_row(const uchar * buf) override; int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, - enum ha_rkey_function find_flag); + enum ha_rkey_function find_flag) override; int index_read_idx_map(uchar *buf, uint index, const uchar *key, key_part_map keypart_map, - enum ha_rkey_function find_flag); - int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map); - int index_next(uchar * buf); - int index_prev(uchar * buf); - int index_first(uchar * buf); - int index_last(uchar * buf); - int index_next_same(uchar *buf, const uchar *key, uint keylen); - int rnd_init(bool scan); - int rnd_next(uchar *buf); - int rnd_pos(uchar * buf, uchar *pos); - void position(const uchar *record); + enum ha_rkey_function find_flag) override; + int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map) override; + int index_next(uchar * buf) override; + int index_prev(uchar * buf) override; + int index_first(uchar * buf) override; + int index_last(uchar * buf) override; + int index_next_same(uchar *buf, const uchar *key, uint keylen) override; + int rnd_init(bool scan) override; + int rnd_next(uchar *buf) override; + int rnd_pos(uchar * buf, uchar *pos) override; + void position(const uchar *record) override; ha_rows records_in_range(uint inx, const key_range *start_key, - const key_range *end_key, page_range *pages); - int delete_all_rows(); - int info(uint); - int reset(void); - int extra(enum ha_extra_function operation); - int extra_opt(enum ha_extra_function operation, ulong cache_size); - int external_lock(THD *thd, int lock_type); - uint lock_count(void) const; - int create_mrg(const char *name, HA_CREATE_INFO *create_info); - int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); + const key_range *end_key, page_range *pages) override; + int delete_all_rows() override; + int info(uint) override; + int reset(void) override; + int extra(enum ha_extra_function operation) override; + int extra_opt(enum ha_extra_function operation, ulong cache_size) override; + int external_lock(THD *thd, int lock_type) override; + uint lock_count(void) const override; + int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info) override; THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, - enum thr_lock_type lock_type); - void update_create_info(HA_CREATE_INFO *create_info); - void append_create_info(String *packet); - MYRG_INFO *myrg_info() { return file; } - TABLE *table_ptr() { return table; } + enum thr_lock_type lock_type) override; + void update_create_info(HA_CREATE_INFO *create_info) override; + void append_create_info(String *packet) override; enum_alter_inplace_result check_if_supported_inplace_alter(TABLE *, - Alter_inplace_info *); + Alter_inplace_info *) override; bool inplace_alter_table(TABLE *altered_table, - Alter_inplace_info *ha_alter_info); - int check(THD* thd, HA_CHECK_OPT* check_opt); - ha_rows records(); - virtual uint count_query_cache_dependant_tables(uint8 *tables_type); + Alter_inplace_info *ha_alter_info) override; + int check(THD* thd, HA_CHECK_OPT* check_opt) override; + ha_rows records() override; + virtual uint count_query_cache_dependant_tables(uint8 *tables_type) override; virtual my_bool register_query_cache_dependant_tables(THD *thd, Query_cache *cache, Query_cache_block_table **block, - uint *n); - virtual void set_lock_type(enum thr_lock_type lock); + uint *n) override; + virtual void set_lock_type(enum thr_lock_type lock) override; + + /* Internal interface functions, not part of the normal handler interface */ + int add_children_list(void); + int attach_children(void); + int detach_children(void); + int create_mrg(const char *name, HA_CREATE_INFO *create_info); + MYRG_INFO *myrg_info() { return file; } + TABLE *table_ptr() { return table; } }; diff --git a/storage/oqgraph/ha_oqgraph.h b/storage/oqgraph/ha_oqgraph.h index c8e175df616..d1f5a898ad7 100644 --- a/storage/oqgraph/ha_oqgraph.h +++ b/storage/oqgraph/ha_oqgraph.h @@ -74,9 +74,10 @@ public: const char **bas_ext() const; uint max_supported_keys() const { return MAX_KEY; } uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; } - double scan_time() { return (double) 1000000000; } - double read_time(uint index, uint ranges, ha_rows rows) - { return 1; } + IO_AND_CPU_COST scan_time() + { return { (double) 1000000000, (double) 1000000000 }; } + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) + { return { (double) rows, (double) rows }; } // Doesn't make sense to change the engine on a virtual table. virtual bool can_switch_engines() { return false; } diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h index eab97434265..20ed7448a1e 100644 --- a/storage/perfschema/ha_perfschema.h +++ b/storage/perfschema/ha_perfschema.h @@ -104,8 +104,10 @@ public: ha_rows estimate_rows_upper_bound(void) { return HA_POS_ERROR; } - double scan_time(void) - { return 1.0; } + IO_AND_CPU_COST scan_time(void) + { + return {0.0, 1.0}; + } /** Open a performance schema table. diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 8203a2ac943..7c1af7217ca 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -5235,6 +5235,24 @@ static int rocksdb_check_version(handlerton *hton, return (create_id == ver); } + +/* + Setup costs factors for RocksDB to be able to approximate how many + ms different opperations takes. See cost functions in handler.h how + the different variables are used +*/ + +static void rocksdb_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + /* See optimizer_costs.txt for how these are calculated */ + costs->row_next_find_cost= 0.00015161; + costs->row_lookup_cost= 0.00150453; + costs->key_next_find_cost= 0.00025108; + costs->key_lookup_cost= 0.00079369; + costs->row_copy_cost= 0.00006087; +} + + /* Storage Engine initialization function, invoked when plugin is loaded. */ @@ -5343,6 +5361,7 @@ static int rocksdb_init_func(void *const p) { rocksdb_hton->savepoint_rollback = rocksdb_rollback_to_savepoint; rocksdb_hton->savepoint_rollback_can_release_mdl = rocksdb_rollback_to_savepoint_can_release_mdl; + rocksdb_hton->update_optimizer_costs= rocksdb_update_optimizer_costs; #ifdef MARIAROCKS_NOT_YET rocksdb_hton->update_table_stats = rocksdb_update_table_stats; #endif // MARIAROCKS_NOT_YET @@ -14631,17 +14650,25 @@ bool ha_rocksdb::use_read_free_rpl() const { } #endif // MARIAROCKS_NOT_YET -double ha_rocksdb::read_time(uint index, uint ranges, ha_rows rows) { +IO_AND_CPU_COST ha_rocksdb::keyread_time(uint index, ulong ranges, + ha_rows rows, + ulonglong blocks) { DBUG_ENTER_FUNC(); - - if (index != table->s->primary_key) { - /* Non covering index range scan */ - DBUG_RETURN(handler::read_time(index, ranges, rows)); - } - - DBUG_RETURN((rows / 20.0) + 1); + IO_AND_CPU_COST cost; + cost= handler::keyread_time(index, ranges, rows, blocks); + cost.io/= 4; // Assume 75% compression (75% less IO) + DBUG_RETURN(cost); } + +ulonglong ha_rocksdb::index_blocks(uint index, uint ranges, ha_rows rows) +{ + size_t len= table->key_storage_length(index); + ulonglong blocks= (rows * len / 4) / stats.block_size + ranges; // 75 % compression + return blocks * stats.block_size / IO_SIZE; +} + + void ha_rocksdb::print_error(int error, myf errflag) { if (error == HA_ERR_ROCKSDB_STATUS_BUSY) { error = HA_ERR_LOCK_DEADLOCK; diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h index 2d6400231fc..f05f373cbfd 100644 --- a/storage/rocksdb/ha_rocksdb.h +++ b/storage/rocksdb/ha_rocksdb.h @@ -623,15 +623,19 @@ public: bool sorted) override MY_ATTRIBUTE((__warn_unused_result__)); - virtual double scan_time() override { + IO_AND_CPU_COST scan_time() override + { + IO_AND_CPU_COST cost; DBUG_ENTER_FUNC(); - - DBUG_RETURN( - static_cast((stats.records + stats.deleted) / 20.0 + 10)); + cost= handler::scan_time(); + cost.cpu+= stats.deleted * ROW_NEXT_FIND_COST; // We have to skip over deleted rows + DBUG_RETURN(cost); } + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, + ha_rows rows, ulonglong blocks) override; - virtual double read_time(uint, uint, ha_rows rows) override; - virtual void print_error(int error, myf errflag) override; + ulonglong index_blocks(uint index, uint ranges, ha_rows rows) override; + void print_error(int error, myf errflag) override; int open(const char *const name, int mode, uint test_if_locked) override MY_ATTRIBUTE((__warn_unused_result__)); diff --git a/storage/rocksdb/mysql-test/rocksdb/include/rocksdb_icp.inc b/storage/rocksdb/mysql-test/rocksdb/include/rocksdb_icp.inc index c76b52d4cc1..bf593ec9b0c 100644 --- a/storage/rocksdb/mysql-test/rocksdb/include/rocksdb_icp.inc +++ b/storage/rocksdb/mysql-test/rocksdb/include/rocksdb_icp.inc @@ -49,7 +49,7 @@ insert into t3 select a,a/10,a,a from t1; explain select * from t3 where kp1=3 and kp2 like '%foo%'; ---replace_column 9 # +--source include/explain-no-costs.inc explain format=json select * from t3 where kp1 between 2 and 4 and mod(kp1,3)=0 and kp2 like '%foo%'; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars_thread_2.result b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars_thread_2.result index 6bd6cea97de..a14ffdec2e3 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars_thread_2.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars_thread_2.result @@ -92,7 +92,5 @@ disconnect con2; disconnect con1; disconnect con0; SELECT * FROM t1 ORDER BY pk INTO OUTFILE ; -Warnings: -Warning 1287 ' INTO FROM...' instead All pk values matched their expected values DROP TABLE t1; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter4.result b/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter4.result index c4a1c5f4668..1f4d1a641a2 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter4.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter4.result @@ -20,8 +20,6 @@ END IF; SET id1_cond = id1_cond + 1; END WHILE; END// -Warnings: -Warning 1287 ' INTO FROM...' instead "Skipping bloom filter" SET session rocksdb_skip_bloom_filter_on_read=1; CALL select_test(); diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result index 730e12d02f6..6645a33e356 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result @@ -39,8 +39,8 @@ a varchar(10) NOT NULL, e int(11) DEFAULT 0, KEY (a) ) ENGINE=ROCKSDB DEFAULT CHARSET=utf8; -insert into t1 values (1,1,1),(2,2,2); -explain select a from t1 where a <'zzz'; +insert into t1 values (1,"a",1),(2,"b",2),(3,"c",2); +explain select a from t1 where a <'b'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 32 NULL # Using where CREATE TABLE t2( diff --git a/storage/rocksdb/mysql-test/rocksdb/r/no_merge_sort.result b/storage/rocksdb/mysql-test/rocksdb/r/no_merge_sort.result index 6ea13872033..3a631d2925b 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/no_merge_sort.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/no_merge_sort.result @@ -1,123 +1,63 @@ Warnings: Note 1051 Unknown table 'test.ti_nk' -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true -Warnings: -Warning 1287 ' INTO FROM...' instead skip_merge_sort true DROP TABLE ti_nk; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result index 989d28e773d..0c9d29efa28 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result @@ -278,12 +278,12 @@ j 1 4 EXPLAIN -SELECT * FROM t10, t11 WHERE i=j; +SELECT * FROM t11 straight_join t10 WHERE i=j; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t10 index PRIMARY PRIMARY 4 NULL # Using index -1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t10.i # Using index -SELECT * FROM t10, t11 WHERE i=j; -i j +1 SIMPLE t11 index PRIMARY PRIMARY 4 NULL # Using index +1 SIMPLE t10 eq_ref PRIMARY PRIMARY 4 test.t11.j # Using index +SELECT * FROM t11 straight_join t10 WHERE i=j; +j i 1 1 DROP TABLE t10,t11; # diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp.result index f9e3129c73f..a4717570450 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp.result @@ -47,6 +47,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -56,7 +57,9 @@ EXPLAIN "key": "kp1", "key_length": "5", "used_key_parts": ["kp1"], + "loops": 1, "rows": 1000, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t3.kp1 between 2 and 4 and t3.kp1 MOD 3 = 0", "attached_condition": "t3.kp2 like '%foo%'" diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp_rev.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp_rev.result index 3634f8c023e..07bce244792 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp_rev.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_icp_rev.result @@ -47,6 +47,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "cost": "COST_REPLACED", "nested_loop": [ { "table": { @@ -56,7 +57,9 @@ EXPLAIN "key": "kp1", "key_length": "5", "used_key_parts": ["kp1"], + "loops": 1, "rows": 1000, + "cost": "COST_REPLACED", "filtered": 100, "index_condition": "t3.kp1 between 2 and 4 and t3.kp1 MOD 3 = 0", "attached_condition": "t3.kp2 like '%foo%'" diff --git a/storage/rocksdb/mysql-test/rocksdb/r/select.result b/storage/rocksdb/mysql-test/rocksdb/r/select.result index 7ea43adc9ea..fc3825d5377 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/select.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/select.result @@ -115,8 +115,6 @@ SELECT t1.a, t2.b FROM t2, t1 WHERE t1.a = t2.a ORDER BY t2.b, t1.a INTO OUTFILE '/select.out' CHARACTER SET utf8 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY ''''; -Warnings: -Warning 1287 ' INTO FROM...' instead 200,'bar' 200,'bar' 100,'foobar' @@ -128,12 +126,8 @@ INTO DUMPFILE '/select.dump'; ERROR 42000: Result consisted of more than one row SELECT t1.*, t2.* FROM t1, t2 ORDER BY t2.b, t1.a, t2.a, t1.b, t1.pk, t2.pk LIMIT 1 INTO DUMPFILE '/select.dump'; -Warnings: -Warning 1287 ' INTO FROM...' instead 1z2200bar3 SELECT MIN(a), MAX(a) FROM t1 INTO @min, @max; -Warnings: -Warning 1287 ' INTO FROM...' instead SELECT @min, @max; @min @max 1 200 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/type_char_indexes.result b/storage/rocksdb/mysql-test/rocksdb/r/type_char_indexes.result index 3c9c30bb617..39413ea5987 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/type_char_indexes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/type_char_indexes.result @@ -45,7 +45,7 @@ t1 1 v16 1 v16 A 500 NULL NULL YES LSMTREE NO INSERT INTO t1 (c,c20,v16,v128,pk) VALUES ('a','char1','varchar1a','varchar1b','1'),('a','char2','varchar2a','varchar2b','2'),('b','char3','varchar1a','varchar1b','3'),('c','char4','varchar3a','varchar3b','4'); EXPLAIN SELECT SUBSTRING(v16,0,3) FROM t1 WHERE v16 LIKE 'varchar%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v16 v16 19 NULL # Using where; Using index +1 SIMPLE t1 index v16 v16 19 NULL # Using where; Using index SELECT SUBSTRING(v16,7,3) FROM t1 WHERE v16 LIKE 'varchar%'; SUBSTRING(v16,7,3) r1a diff --git a/storage/rocksdb/mysql-test/rocksdb/r/type_date_time_indexes.result b/storage/rocksdb/mysql-test/rocksdb/r/type_date_time_indexes.result index bd40e32f94d..5e89648648d 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/type_date_time_indexes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/type_date_time_indexes.result @@ -62,7 +62,7 @@ INSERT INTO t1 (d,dt,ts,t,y,pk) VALUES (DATE(@tm),@tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),'12:05:00'); EXPLAIN SELECT ts FROM t1 WHERE ts > NOW(); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range ts ts 5 NULL # Using where; Using index +1 SIMPLE t1 index ts ts 5 NULL # Using where; Using index SELECT ts FROM t1 WHERE ts > NOW(); ts EXPLAIN SELECT ts FROM t1 USE INDEX () WHERE ts > NOW(); diff --git a/storage/rocksdb/mysql-test/rocksdb/r/type_enum_indexes.result b/storage/rocksdb/mysql-test/rocksdb/r/type_enum_indexes.result index b0bcfd7075c..011fa0894ec 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/type_enum_indexes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/type_enum_indexes.result @@ -49,7 +49,7 @@ t1 0 PRIMARY 1 pk A 1000 NULL NULL LSMTREE NO t1 1 b 1 b A 500 NULL NULL YES LSMTREE NO EXPLAIN SELECT DISTINCT b FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL b 2 NULL # +1 SIMPLE t1 ALL NULL NULL NULL NULL # Using temporary SELECT DISTINCT b FROM t1; b test1 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/type_float_indexes.result b/storage/rocksdb/mysql-test/rocksdb/r/type_float_indexes.result index 89dc65e56f8..a98f90f28da 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/type_float_indexes.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/type_float_indexes.result @@ -114,7 +114,7 @@ INSERT INTO t1 (f,r,d,dp,pk) VALUES (4644,1422.22,466664.999,0.5,5); EXPLAIN SELECT DISTINCT d FROM t1 ORDER BY d; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL d 9 NULL # Using index for group-by +1 SIMPLE t1 index NULL d 9 NULL # Using index SELECT DISTINCT d FROM t1 ORDER BY d; d -1 @@ -177,7 +177,7 @@ INSERT INTO t1 (f,r,d,dp,pk) VALUES (1.2345,0,0,0,6); EXPLAIN SELECT DISTINCT f FROM t1 ORDER BY f; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL f 5 NULL # Using index for group-by +1 SIMPLE t1 index NULL f 5 NULL # Using index SELECT DISTINCT f FROM t1 ORDER BY f; f -1 diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test index 99d4e2d117c..da4ac350654 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_fixes.test @@ -37,9 +37,9 @@ CREATE TABLE t1( e int(11) DEFAULT 0, KEY (a) ) ENGINE=ROCKSDB DEFAULT CHARSET=utf8; -insert into t1 values (1,1,1),(2,2,2); +insert into t1 values (1,"a",1),(2,"b",2),(3,"c",2); --replace_column 9 # -explain select a from t1 where a <'zzz'; +explain select a from t1 where a <'b'; CREATE TABLE t2( pk int, diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test index f7de167bd96..9b24ad952d7 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test @@ -266,8 +266,8 @@ select * from t10; select * from t11; --replace_column 9 # EXPLAIN -SELECT * FROM t10, t11 WHERE i=j; -SELECT * FROM t10, t11 WHERE i=j; +SELECT * FROM t11 straight_join t10 WHERE i=j; +SELECT * FROM t11 straight_join t10 WHERE i=j; DROP TABLE t10,t11; diff --git a/storage/sequence/mysql-test/sequence/group_by.result b/storage/sequence/mysql-test/sequence/group_by.result index bcda2ba5c76..7c098de9afd 100644 --- a/storage/sequence/mysql-test/sequence/group_by.result +++ b/storage/sequence/mysql-test/sequence/group_by.result @@ -86,7 +86,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL PRIMARY 8 NULL 8 Using index; Using join buffer (flat, BNL join) explain select count(*) from seq_1_to_15_step_2 where seq > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE seq_1_to_15_step_2 index PRIMARY PRIMARY 8 NULL 8 Using where; Using index +1 SIMPLE seq_1_to_15_step_2 range PRIMARY PRIMARY 8 NULL 8 Using where; Using index explain select count(*) from seq_1_to_15_step_2 group by mod(seq,2); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE seq_1_to_15_step_2 index NULL PRIMARY 8 NULL 8 Using index; Using temporary; Using filesort diff --git a/storage/sequence/sequence.cc b/storage/sequence/sequence.cc index f5a18094521..38e1eea8c40 100644 --- a/storage/sequence/sequence.cc +++ b/storage/sequence/sequence.cc @@ -64,45 +64,53 @@ public: Sequence_share *seqs; ha_seq(handlerton *hton, TABLE_SHARE *table_arg) : handler(hton, table_arg), seqs(0) { } - ulonglong table_flags() const + ulonglong table_flags() const override { return HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE; } /* open/close/locking */ int create(const char *name, TABLE *table_arg, - HA_CREATE_INFO *create_info) + HA_CREATE_INFO *create_info) override { return HA_ERR_WRONG_COMMAND; } - int open(const char *name, int mode, uint test_if_locked); - int close(void); - int delete_table(const char *name) + int open(const char *name, int mode, uint test_if_locked) override; + int close(void) override; + int delete_table(const char *name) override { return 0; } - THR_LOCK_DATA **store_lock(THD *, THR_LOCK_DATA **, enum thr_lock_type); + THR_LOCK_DATA **store_lock(THD *, THR_LOCK_DATA **, enum thr_lock_type) + override; /* table scan */ - int rnd_init(bool scan); - int rnd_next(unsigned char *buf); - void position(const uchar *record); - int rnd_pos(uchar *buf, uchar *pos); - int info(uint flag); - + int rnd_init(bool scan) override; + int rnd_next(unsigned char *buf) override; + void position(const uchar *record) override; + int rnd_pos(uchar *buf, uchar *pos) override; + int info(uint flag) override; + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) override + { + /* Avoids assert in total_cost() and makes DBUG_PRINT more consistent */ + return {0,0}; + } + IO_AND_CPU_COST scan_time() override + { + /* Avoids assert in total_cost() and makes DBUG_PRINT more consistent */ + return {0, 0}; + } /* indexes */ - ulong index_flags(uint inx, uint part, bool all_parts) const + ulong index_flags(uint inx, uint part, bool all_parts) const override { return HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE | HA_KEYREAD_ONLY; } - uint max_supported_keys() const { return 1; } + uint max_supported_keys() const override { return 1; } int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, - enum ha_rkey_function find_flag); - int index_next(uchar *buf); - int index_prev(uchar *buf); - int index_first(uchar *buf); - int index_last(uchar *buf); + enum ha_rkey_function find_flag) override; + int index_next(uchar *buf) override; + int index_prev(uchar *buf) override; + int index_first(uchar *buf) override; + int index_last(uchar *buf) override; ha_rows records_in_range(uint inx, const key_range *start_key, - const key_range *end_key, page_range *pages); - double scan_time() { return (double)nvalues(); } - double read_time(uint index, uint ranges, ha_rows rows) { return (double)rows; } - double keyread_time(uint index, uint ranges, ha_rows rows) { return (double)rows; } + const key_range *end_key, page_range *pages) override; private: void set(uchar *buf); @@ -492,6 +500,17 @@ int ha_seq_group_by_handler::next_row() DBUG_RETURN(0); } +static void sequence_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + costs->disk_read_cost= 0; + costs->disk_read_ratio= 0.0; // No disk + costs->key_next_find_cost= + costs->key_lookup_cost= + costs->key_copy_cost= + costs->row_next_find_cost= + costs->row_lookup_cost= + costs->row_copy_cost= 0.0000062391530550; +} /***************************************************************************** Initialize the interface between the sequence engine and MariaDB @@ -518,6 +537,7 @@ static int init(void *p) hton->savepoint_set= hton->savepoint_rollback= hton->savepoint_release= dummy_savepoint; hton->create_group_by= create_group_by_handler; + hton->update_optimizer_costs= sequence_update_optimizer_costs; return 0; } diff --git a/storage/sphinx/ha_sphinx.h b/storage/sphinx/ha_sphinx.h index f03e9d8c797..f5651fc6eb5 100644 --- a/storage/sphinx/ha_sphinx.h +++ b/storage/sphinx/ha_sphinx.h @@ -72,14 +72,28 @@ public: uint max_supported_key_length () const { return MAX_KEY_LENGTH; } uint max_supported_key_part_length () const { return MAX_KEY_LENGTH; } - #if MYSQL_VERSION_ID>50100 - virtual double scan_time () { return (double)( stats.records+stats.deleted )/20.0 + 10; } ///< called in test_quick_select to determine if indexes should be used - #else - virtual double scan_time () { return (double)( records+deleted )/20.0 + 10; } ///< called in test_quick_select to determine if indexes should be used - #endif - - virtual double read_time(uint index, uint ranges, ha_rows rows) - { return ranges + (double)rows/20.0 + 1; } ///< index read time estimate + IO_AND_CPU_COST scan_time () + { + IO_AND_CPU_COST cost; + cost.io= 0; + cost.cpu= (double) (stats.records+stats.deleted) * DISK_READ_COST; + return cost; + } + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) + { + IO_AND_CPU_COST cost; + cost.io= ranges; + cost.cpu= 0; + return cost; + } + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) + { + IO_AND_CPU_COST cost; + cost.io= 0; + cost.cpu= 0; + return cost; + } public: int open ( const char * name, int mode, uint test_if_locked ); diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 070d8ec0dd4..5cf67a091db 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -3151,6 +3151,7 @@ ha_rows ha_spider::multi_range_read_info_const( uint n_ranges, uint *bufsz, uint *flags, + ha_rows limit, Cost_estimate *cost ) { @@ -3190,6 +3191,7 @@ ha_rows ha_spider::multi_range_read_info_const( n_ranges, bufsz, flags, + limit, cost ); *flags &= ~HA_MRR_USE_DEFAULT_IMPL; @@ -8484,38 +8486,47 @@ int ha_spider::truncate() DBUG_RETURN(0); } - -double ha_spider::scan_time() +IO_AND_CPU_COST ha_spider::scan_time() { + IO_AND_CPU_COST cost; DBUG_ENTER("ha_spider::scan_time"); DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider scan_time = %.6f", - share->scan_rate * share->stat.records * share->stat.mean_rec_length + 2)); - DBUG_RETURN(share->scan_rate * share->stat.records * - share->stat.mean_rec_length + 2); + cost.io=0; + cost.cpu= (DISK_READ_COST * share->stat.records * share->stat.mean_rec_length); + DBUG_PRINT("info",("spider scan_time = %.6f", cost.cpu)); + DBUG_RETURN(cost); } -double ha_spider::read_time( - uint index, - uint ranges, - ha_rows rows -) { - DBUG_ENTER("ha_spider::read_time"); +IO_AND_CPU_COST ha_spider::rnd_pos_time(ha_rows rows) +{ + IO_AND_CPU_COST cost= { 0.0, 0.0}; // Row is in memory + return cost; +} + +IO_AND_CPU_COST ha_spider::keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) +{ + IO_AND_CPU_COST cost; + DBUG_ENTER("ha_spider::keyread_time"); DBUG_PRINT("info",("spider this=%p", this)); + + /* + Here we only calculate transfer costs. The normal handler cost functions + will add costs for accessing a row/key. + */ if (wide_handler->keyread) { - DBUG_PRINT("info",("spider read_time(keyread) = %.6f", - share->read_rate * table->key_info[index].key_length * - rows / 2 + 2)); - DBUG_RETURN(share->read_rate * table->key_info[index].key_length * - rows / 2 + 2); + cost.io= 0; + cost.cpu= DISK_READ_COST * rows * table->key_info[index].key_length; } else { - DBUG_PRINT("info",("spider read_time = %.6f", - share->read_rate * share->stat.mean_rec_length * rows + 2)); - DBUG_RETURN(share->read_rate * share->stat.mean_rec_length * rows + 2); + cost.io= 0; + cost.cpu= DISK_READ_COST * rows * share->stat.mean_rec_length; } + DBUG_PRINT("info",("spider scan_time(keyread) = %.6f", cost.cpu)); + DBUG_RETURN(cost); } + const key_map *ha_spider::keys_to_use_for_scanning() { DBUG_ENTER("ha_spider::keys_to_use_for_scanning"); diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index f6efc62dfe6..ac865e78f2c 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -250,6 +250,7 @@ public: uint n_ranges, uint *bufsz, uint *flags, + ha_rows limit, Cost_estimate *cost ); ha_rows multi_range_read_info( @@ -443,12 +444,10 @@ public: ); int delete_all_rows(); int truncate(); - double scan_time(); - double read_time( - uint index, - uint ranges, - ha_rows rows - ); + IO_AND_CPU_COST scan_time(); + IO_AND_CPU_COST rnd_pos_time(ha_rows rows); + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks); const key_map *keys_to_use_for_scanning(); ha_rows estimate_rows_upper_bound(); void print_error( diff --git a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result index a6a7588b014..2f54ef93a13 100644 --- a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result +++ b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result @@ -481,7 +481,6 @@ DELETE FROM t1; Warnings: Error 12702 Remote table 'auto_test_remote.ter1_1' is not found Error 12702 Remote table 'auto_test_remote.ter1_1' is not found -Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist TRUNCATE t1; Warnings: Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist diff --git a/storage/spider/mysql-test/spider/bugfix/r/quick_mode_1.result b/storage/spider/mysql-test/spider/bugfix/r/quick_mode_1.result index 89a07bf64e6..62e1b2e64b2 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/quick_mode_1.result +++ b/storage/spider/mysql-test/spider/bugfix/r/quick_mode_1.result @@ -57,6 +57,10 @@ TRUNCATE TABLE mysql.general_log; connection child2_2; TRUNCATE TABLE mysql.general_log; connection master_1; +explain SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey = b.pkey; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a index PRIMARY PRIMARY 4 NULL 2 Using index +1 SIMPLE b eq_ref PRIMARY PRIMARY 4 auto_test_local.a.pkey 1 Using index SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey = b.pkey; pkey 0 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_22246.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_22246.test index 9e58bc1a836..be993647bb9 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_22246.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_22246.test @@ -64,6 +64,7 @@ TRUNCATE TABLE mysql.general_log; --connection master_1 SELECT * FROM tbl_a; +--sorted_result SELECT * FROM tbl_a WHERE id <0 || id >0; --connection child2_1 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.test index 60c0ad42921..02a4b803a89 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.test @@ -2,6 +2,10 @@ --echo # MDEV-27172 Prefix indices on Spider tables may lead to wrong query results --echo # +# Disable test for ps-protocol as the general log has different number of +# commands for --ps +--source include/no_protocol.inc + --disable_query_log --disable_result_log --source ../../t/test_init.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/quick_mode_1.test b/storage/spider/mysql-test/spider/bugfix/t/quick_mode_1.test index 01fa0cb5128..c878a738c53 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/quick_mode_1.test +++ b/storage/spider/mysql-test/spider/bugfix/t/quick_mode_1.test @@ -74,6 +74,7 @@ TRUNCATE TABLE mysql.general_log; TRUNCATE TABLE mysql.general_log; --connection master_1 +explain SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey = b.pkey; SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey = b.pkey; --connection child2_1 diff --git a/storage/spider/mysql-test/spider/r/direct_left_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_left_join_nullable.result index 4adfb1bd76a..83ec42044a5 100644 --- a/storage/spider/mysql-test/spider/r/direct_left_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_left_join_nullable.result @@ -87,7 +87,7 @@ a b c a connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t0 left join `auto_test_remote`.`ta_r_auto_inc` t1 on (t1.`a` = t0.`a`) left join `auto_test_remote`.`ta_r_3` t2 on (t2.`c` = t1.`c`) left join `auto_test_remote`.`ta_r` t3 on (t3.`b` = t2.`b`) where 1 order by t0.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t0 left join `auto_test_remote`.`ta_r_auto_inc` t1 on ((t1.`a` = t0.`a`) and (t0.`a` is not null)) left join `auto_test_remote`.`ta_r_3` t2 on (t2.`c` = t1.`c`) left join `auto_test_remote`.`ta_r` t3 on ((t3.`b` = t2.`b`) and (t2.`b` is not null)) where 1 order by t0.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_left_right_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_left_right_join_nullable.result index a6bd3a7c1a1..ff4f211faf5 100644 --- a/storage/spider/mysql-test/spider/r/direct_left_right_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_left_right_join_nullable.result @@ -87,7 +87,7 @@ NULL NULL NULL 3 connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r_auto_inc` t2 join `auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r` t0) on ((t2.`b` = t3.`b`) and (t2.`c` = t1.`c`) and (t0.`a` = t1.`a`) and (t1.`a` is not null)) where 1 order by t3.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r_auto_inc` t2 join `auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r` t0) on ((t2.`b` = t3.`b`) and (t1.`c` = t2.`c`) and (t0.`a` = t1.`a`) and (t3.`b` is not null) and (t1.`a` is not null)) where 1 order by t3.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_right_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_right_join_nullable.result index 5101ea5036a..02f985279f8 100644 --- a/storage/spider/mysql-test/spider/r/direct_right_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_right_join_nullable.result @@ -87,7 +87,7 @@ NULL c 2000-01-03 00:00:00 3 connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join `auto_test_remote`.`ta_r_auto_inc` t2 on (t2.`b` = t3.`b`) left join `auto_test_remote`.`ta_r_3` t1 on (t1.`c` = t2.`c`) left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null)) where 1 order by t3.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join `auto_test_remote`.`ta_r_auto_inc` t2 on ((t2.`b` = t3.`b`) and (t3.`b` is not null)) left join `auto_test_remote`.`ta_r_3` t1 on (t1.`c` = t2.`c`) left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null)) where 1 order by t3.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_right_left_right_join_nullable.result b/storage/spider/mysql-test/spider/r/direct_right_left_right_join_nullable.result index f6c808be973..840328508fa 100644 --- a/storage/spider/mysql-test/spider/r/direct_right_left_right_join_nullable.result +++ b/storage/spider/mysql-test/spider/r/direct_right_left_right_join_nullable.result @@ -87,7 +87,7 @@ NULL c 2000-01-03 00:00:00 3 connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r_auto_inc` t2 join `auto_test_remote`.`ta_r_3` t1 left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null))) on ((t2.`b` = t3.`b`) and (t2.`c` = t1.`c`)) where 1 order by t3.`a` desc +select t0.`a` `a`,t2.`b` `b`,t2.`c` `c`,t3.`a` `a` from `auto_test_remote`.`ta_r_no_idx` t3 left join (`auto_test_remote`.`ta_r_auto_inc` t2 join `auto_test_remote`.`ta_r_3` t1 left join `auto_test_remote`.`ta_r` t0 on ((t0.`a` = t1.`a`) and (t1.`a` is not null))) on ((t2.`b` = t3.`b`) and (t1.`c` = t2.`c`) and (t3.`b` is not null)) where 1 order by t3.`a` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/partition_mrr.result b/storage/spider/mysql-test/spider/r/partition_mrr.result index c1b7d6e6a4a..61878a15698 100644 --- a/storage/spider/mysql-test/spider/r/partition_mrr.result +++ b/storage/spider/mysql-test/spider/r/partition_mrr.result @@ -74,36 +74,36 @@ TRUNCATE TABLE mysql.general_log; connection master_1; SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey = b.pkey; pkey -4 -5 -10 -11 -16 -17 -22 -23 -28 -29 0 1 -6 -7 +10 +11 12 13 -18 -19 -24 -25 -2 -3 -8 -9 14 15 +16 +17 +18 +19 +2 20 21 +22 +23 +24 +25 26 27 +28 +29 +3 +4 +5 +6 +7 +8 +9 SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey+0 = b.pkey+0 ORDER BY a.pkey; pkey 0 @@ -140,7 +140,9 @@ connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument select `pkey` from `auto_test_remote`.`tbl_a` order by `pkey` -select a.id,b.`pkey` from auto_test_remote.tmp_spider_bka_xxxx a,`auto_test_remote`.`tbl_b` b where a.c0 <=> b.`pkey` +select `pkey` from `auto_test_remote`.`tbl_b` order by `pkey` +select `pkey` from `auto_test_remote`.`tbl_b` order by `pkey` +select `pkey` from `auto_test_remote`.`tbl_b` order by `pkey` select `pkey` from `auto_test_remote`.`tbl_a` order by `pkey` select `pkey` from `auto_test_remote`.`tbl_b` order by `pkey` select `pkey` from `auto_test_remote`.`tbl_b` order by `pkey` @@ -174,7 +176,9 @@ connection child2_2; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument select `pkey` from `auto_test_remote2`.`tbl_a` order by `pkey` -select a.id,b.`pkey` from auto_test_remote2.tmp_spider_bka_xxxx a,`auto_test_remote2`.`tbl_b` b where a.c0 <=> b.`pkey` +select `pkey` from `auto_test_remote2`.`tbl_b` order by `pkey` +select `pkey` from `auto_test_remote2`.`tbl_b` order by `pkey` +select `pkey` from `auto_test_remote2`.`tbl_b` order by `pkey` select `pkey` from `auto_test_remote2`.`tbl_a` order by `pkey` select `pkey` from `auto_test_remote2`.`tbl_b` order by `pkey` select `pkey` from `auto_test_remote2`.`tbl_b` order by `pkey` @@ -208,7 +212,9 @@ connection child2_3; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument select `pkey` from `auto_test_remote3`.`tbl_a` order by `pkey` -select a.id,b.`pkey` from auto_test_remote3.tmp_spider_bka_xxxx a,`auto_test_remote3`.`tbl_b` b where a.c0 <=> b.`pkey` +select `pkey` from `auto_test_remote3`.`tbl_b` order by `pkey` +select `pkey` from `auto_test_remote3`.`tbl_b` order by `pkey` +select `pkey` from `auto_test_remote3`.`tbl_b` order by `pkey` select `pkey` from `auto_test_remote3`.`tbl_a` order by `pkey` select `pkey` from `auto_test_remote3`.`tbl_b` order by `pkey` select `pkey` from `auto_test_remote3`.`tbl_b` order by `pkey` diff --git a/storage/spider/mysql-test/spider/r/spider_fixes.result b/storage/spider/mysql-test/spider/r/spider_fixes.result index 3b9d939393a..5e17e83618e 100644 --- a/storage/spider/mysql-test/spider/r/spider_fixes.result +++ b/storage/spider/mysql-test/spider/r/spider_fixes.result @@ -481,7 +481,6 @@ DELETE FROM t1; Warnings: Error 12702 Remote table 'auto_test_remote.ter1_1' is not found Error 12702 Remote table 'auto_test_remote.ter1_1' is not found -Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist TRUNCATE t1; Warnings: Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist diff --git a/storage/spider/mysql-test/spider/t/partition_mrr.test b/storage/spider/mysql-test/spider/t/partition_mrr.test index 23f4fdb6e27..6c431401e18 100644 --- a/storage/spider/mysql-test/spider/t/partition_mrr.test +++ b/storage/spider/mysql-test/spider/t/partition_mrr.test @@ -168,6 +168,7 @@ if ($USE_CHILD_GROUP2) } } --connection master_1 +--sorted_result SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey = b.pkey; SELECT a.pkey FROM tbl_a a, tbl_b b WHERE a.pkey+0 = b.pkey+0 ORDER BY a.pkey; # MDEV-29947 if ($USE_CHILD_GROUP2) diff --git a/storage/spider/spd_init_query.h b/storage/spider/spd_init_query.h index 0aba850ce0f..c3bea1c166b 100644 --- a/storage/spider/spd_init_query.h +++ b/storage/spider/spd_init_query.h @@ -544,11 +544,7 @@ static LEX_STRING spider_init_queries[] = { /* " if @server_name = 'MariaDB' and" " (" - " @server_major_version > 10 or" - " (" - " @server_major_version = 10 and" - " @server_minor_version >= 999" - " )" + " @server_major_version > 11" " )" " then" " create table if not exists mysql.spider_rewrite_tables(" @@ -806,13 +802,9 @@ static LEX_STRING spider_init_queries[] = { Install spider_rewrite plugin */ /* - " if @server_name = 'MariaDB' and" + " if @server_name = 'MariaDB' and " " (" - " @server_major_version > 10 or" - " (" - " @server_major_version = 10 and" - " @server_minor_version >= 999" - " )" + " @server_major_version > 11" " )" " then" " set @have_spider_i_s_rewrite_plugin := 0;" diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index e6ecf96de1c..5bafc4e04ed 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -6510,6 +6510,25 @@ int spider_panic( DBUG_RETURN(0); } +static void spider_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + /* Assume 1 Gigabyte network */ + costs->disk_read_cost= IO_SIZE/(1000000000/8)*1000.00000; + costs->index_block_copy_cost= 0; // Not used + + /* + The following costs are copied from ha_innodb.cc + The assumption is that the default storage engine used with Spider is + InnoDB. + */ + costs->row_next_find_cost= 0.00007013; + costs->row_lookup_cost= 0.00076597; + costs->key_next_find_cost= 0.00009900; + costs->key_lookup_cost= 0.00079112; + costs->row_copy_cost= 0.00006087; +} + + int spider_db_init( void *p ) { @@ -6553,6 +6572,7 @@ int spider_db_init( spider_hton->show_status = spider_show_status; spider_hton->create_group_by = spider_create_group_by_handler; spider_hton->table_options= spider_table_option_list; + spider_hton->update_optimizer_costs= spider_update_optimizer_costs; if (my_gethwaddr((uchar *) addr)) { diff --git a/tests/check_costs.pl b/tests/check_costs.pl new file mode 100755 index 00000000000..2709d482c9a --- /dev/null +++ b/tests/check_costs.pl @@ -0,0 +1,1005 @@ +#!/usr/bin/env perl + +# Copyright (C) 2022 MariaDB Foundation +# Use is subject to license terms +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA + +# This is a test that runs queries to meassure if the MariaDB cost calculations +# are reasonable. +# +# The following test are run: +# - Full table scan of a table +# - Range scan of the table +# - Index scan of the table +# +# The output can be used to finetune the optimizer cost variables. +# +# The table in question is a similar to the 'lineitem' table used by DBT3 +# it has 16 field and could be regarded as a 'average kind of table'. +# Number of fields and record length places a small role when comparing +# index scan and table scan + +##################### Standard benchmark inits ############################## + +use DBI; +use Getopt::Long; +use Benchmark ':hireswallclock'; + +package main; + +$opt_rows=1000000; +$opt_test_runs= 2; # Run each test 2 times and take the average +$opt_verbose=""; +$opt_host=""; +$opt_db="test"; +$opt_user="test"; +$opt_password=""; +$opt_socket=undef; +$opt_skip_drop= undef; +$opt_skip_create= undef; +$opt_init_query= undef; +$opt_analyze= undef; +$opt_where_check= undef; +$opt_engine=undef; +$opt_comment=undef; +$opt_table_suffix=undef; +$opt_table_name= undef; +$opt_grof= undef; +$opt_all_tests=undef; +$opt_ratios= undef; +$opt_mysql= undef; +$has_force_index=1; + +@arguments= @ARGV; + +GetOptions("host=s","user=s","password=s", "rows=i","test-runs=i","socket=s", + "db=s", "table-name=s", "skip-drop","skip-create", + "init-query=s","engine=s","comment=s", + "gprof", "one-test=s", + "mysql", "all-tests", "ratios", "where-check", + "analyze", "verbose") || + die "Aborted"; + +$Mysql::db_errstr=undef; # Ignore warnings from these + +my ($base_table, $table, $dbh, $where_cost, $real_where_cost, $perf_ratio); + +if (!$opt_mysql) +{ + @engines= ("aria","innodb","myisam","heap"); +} +else +{ + @engines= ("innodb","myisam","heap"); +} + +# Special handling for some engines + +$no_force= 0; + +if (defined($opt_engine)) +{ + if (lc($engine) eq "archive") + { + $has_force_index= 0; # Skip tests with force index + } +} + + +if (defined($opt_gprof) || defined($opt_one_test)) +{ + die "one_test must be defined when --gprof is used" + if (!defined($opt_one_test)); + die "engine must be defined when --gprof or --one-test is used" + if (!defined($opt_engine)); + die "function '$opt_one_test' does not exist\n" + if (!defined(&{$opt_one_test})); +} + +# We add engine_name to the table name later + +$opt_table_name="check_costs" if (!defined($opt_table_name)); +$base_table="$opt_db.$opt_table_name"; + +#### +#### Start timeing and start test +#### + +$|= 1; # Autoflush +if ($opt_verbose) +{ + $opt_analyze= 1; +} + +#### +#### Create the table +#### + +my %attrib; + +$attrib{'PrintError'}=0; + +if (defined($opt_socket)) +{ + $attrib{'mariadb_socket'}=$opt_socket; +} + +$dbh = DBI->connect("DBI:MariaDB:$opt_db:$opt_host", + $opt_user, $opt_password,\%attrib) || die $DBI::errstr; + +print_mariadb_version(); +print "Server options: $opt_comment\n" if (defined($opt_comment)); +print "Running tests with $opt_rows rows\n"; + +print "Program arguments:\n"; +for ($i= 0 ; $i <= $#arguments; $i++) +{ + my $arg=$arguments[$i]; + if ($arg =~ / /) + { + if ($arg =~ /([^ =]*)=(.*)/) + { + print "$1=\"$2\" "; + } + else + { + print "\"$arg\"" . " "; + } + } + else + { + print $arguments[$i] . " "; + } +} +print "\n\n"; + +@test_names= + ("table scan no where", "table scan simple where", + "table scan where no match", "table scan complex where", "table scan", + "index scan", "index scan 4 parts", "range scan", "eq_ref_index_join", + "eq_ref_cluster_join", "eq_ref_join", "eq_ref_btree"); +$where_tests=3; # Number of where test to be compared with test[0] + +if ($opt_mysql) +{ + create_seq_table(); +} + + +if ($opt_engine || defined($opt_one_test)) +{ + test_engine(0, $opt_engine); +} +else +{ + my $i; + undef($opt_skip_create); + for ($i= 0 ; $i <= $#engines; $i++) + { + test_engine($i, $engines[$i]); + + if ($i > 0 && $opt_ratios) + { + print "\n"; + my $j; + + print "Ratios $engines[$i] / $engines[0]\n"; + for ($j= $where_tests+1 ; $j <= $#test_names ; $j++) + { + if ($res[$i][$j]) + { + my $cmp_cost= $res[0][$j]->{'cost'} - $res[0][$j]->{'where_cost'}; + my $cmp_time= $res[0][$j]->{'time'}; + my $cur_cost= $res[$i][$j]->{'cost'} - $res[$i][$j]->{'where_cost'}; + my $cur_time= $res[$i][$j]->{'time'}; + + printf "%14.14s cost: %6.4f time: %6.4f cost_multiplier: %6.4f\n", + $test_names[$j], + $cur_cost / $cmp_cost, + $cur_time / $cmp_time, + ($cmp_cost * ($cur_time / $cmp_time))/$cur_cost; + } +000000 } + } +# if ($i + 1 <= $#engines) + { + print "-------------------------\n\n"; + } + } + print_totals(); +} + +$dbh->do("drop table if exists $table") if (!defined($opt_skip_drop)); +$dbh->disconnect; $dbh=0; # Close handler +exit(0); + + +sub test_engine() +{ + my ($i, $engine)= @_; + my ($cur_rows); + + setup_engine($engine); + setup($opt_init_query); + $table= $base_table . "_$engine"; + if (!defined($opt_skip_create)) + { + my $index_type=""; + + # We should use btree index with heap to ge range scans + $index_type= "using btree" if (lc($engine) eq "heap"); + + print "Creating table $table of type $engine\n"; + $dbh->do("drop table if exists $table"); + $dbh->do("create table $table ( + `l_orderkey` int(11) NOT NULL, + `l_partkey` int(11) DEFAULT NULL, + `l_suppkey` int(11) DEFAULT NULL, + `l_linenumber` int(11) NOT NULL, + `l_extra` int(11) NOT NULL, + `l_quantity` double DEFAULT NULL, + `l_extendedprice` double DEFAULT NULL, + `l_discount` double DEFAULT NULL, + `l_tax` double DEFAULT NULL, + `l_returnflag` char(1) DEFAULT NULL, + `l_linestatus` char(1) DEFAULT NULL, + `l_shipDATE` date DEFAULT NULL, + `l_commitDATE` date DEFAULT NULL, + `l_receiptDATE` date DEFAULT NULL, + `l_shipinstruct` char(25) DEFAULT NULL, + `l_shipmode` char(10) DEFAULT NULL, + `l_comment` varchar(44) DEFAULT NULL, + PRIMARY KEY (`l_orderkey`), + UNIQUE (`l_linenumber`), + UNIQUE (`l_extra`) $index_type, + KEY `l_suppkey` $index_type (l_suppkey, l_partkey), + KEY `long_suppkey` $index_type + (l_partkey, l_suppkey, l_linenumber, l_extra) ) + ENGINE= $engine") + or die "Got error on CREATE TABLE: $DBI::errstr"; + } + $cur_rows= get_row_count(); + if ($cur_rows == 0 || !defined($opt_skip_create)) + { + $dbh->do("insert into $table select + seq, seq/10, seq, seq, seq, seq, seq, mod(seq,10)*10, + 0, 'a','b', + date_add('2000-01-01', interval seq/500 day), + date_add('2000-01-10', interval seq/500 day), + date_add('2000-01-20', interval seq/500 day), + left(md5(seq),25), + if(seq & 1,'mail','ship'), + repeat('a',mod(seq,40)) + from seq_1_to_$opt_rows") + or die "Got error on INSERT: $DBI::errstr"; + + $sth= $dbh->do("analyze table $table") + or die "Got error on 'analyze table: " . $dbh->errstr . "\n"; + } + else + { + $opt_rows= $cur_rows; + die "Table $table is empty. Please run without --skip-create" + if ($opt_rows == 0); + print "Reusing old table $table, which has $opt_rows rows\n"; + } + + if (!$opt_mysql) + { + $where_cost=get_variable("optimizer_where_cost"); + if (defined($where_cost)) + { + # Calculate cost of where once. Must be done after table is created + $real_where_cost= get_where_cost(); + $perf_ratio= $real_where_cost/$where_cost; + printf "Performance ratio compared to base computer: %6.4f\n", + $perf_ratio; + } + print "\n"; + } + else + { + $where_cost=0.1; # mysql 'm_row_evaluate_cost' + } + + + if (defined($opt_one_test)) + { + if (defined($opt_gprof)) + { + # Argument is the name of the test function + test_with_gprof($opt_one_test, 10); + return; + } + $opt_one_test->(); + return; + } + + if ($opt_where_check) + { + $res[$i][0]= table_scan_without_where(0); + $res[$i][1]= table_scan_with_where(1); + $res[$i][2]= table_scan_with_where_no_match(2); + $res[$i][3]= table_scan_with_complex_where(3); + } + $res[$i][4]= table_scan_without_where_analyze(4); + $res[$i][5]= index_scan(5); + $res[$i][6]= index_scan_4_parts(6) if ($opt_all_tests); + $res[$i][7]= range_scan(7); + $res[$i][8]= eq_ref_index_join(8); + $res[$i][9]= eq_ref_clustered_join(9); + $res[$i][10]= eq_ref_join(10); + $res[$i][11]= eq_ref_join_btree(11); + + if ($opt_where_check) + { + printf "Variable optimizer_where_cost: cur: %6.4f real: %6.4f prop: %6.4f\n", + $where_cost, $real_where_cost, $perf_ratio; + print "Ratio of WHERE costs compared to scan without a WHERE\n"; + for ($j= 1 ; $j <= $where_tests ; $j++) + { + print_where_costs($i,$j,0); + } + print "\n"; + } + + print "Cost/time ratio for different scans types\n"; + for ($j= $where_tests+1 ; $j <= $#test_names ; $j++) + { + if ($res[$i][$j]) + { + print_costs($test_names[$j], $res[$i][$j]); + } + } +} + + +sub print_costs($;$) +{ + my ($name, $cur_res)= @_; + + # Cost without where clause + my $cur_cost= $cur_res->{'cost'} - $cur_res->{'where_cost'}; + my $cur_time= $cur_res->{'time'}; + + printf "%-20.20s cost: %9.4f time: %9.4f cost/time: %8.4f\n", + $name, + $cur_cost, $cur_time, $cur_cost/$cur_time; +} + +sub print_where_costs() +{ + my ($index, $cmp, $base)= @_; + + my $cmp_time= $res[$index][$cmp]->{'time'}; + my $base_time= $res[$index][$base]->{'time'}; + + printf "%-30.30s time: %6.4f\n", $test_names[$cmp], $cmp_time / $base_time; +} + + +# Used to setup things like optimizer_switch or optimizer_cache_hit_ratio + +sub setup() +{ + my ($query)= @_; + my ($sth,$query); + + $sth= $dbh->do("flush tables") || + die "Got error on 'flush tables': " . $dbh->errstr . "\n"; + if (defined($query)) + { + $sth= $dbh->do("$query") || + die "Got error on '$query': " . $dbh->errstr . "\n"; + } + + # Set variables that may interfer with timings + $query= "set \@\@optimizer_switch='index_condition_pushdown=off'"; + $sth= $dbh->do($query) || + die "Got error on '$query': " . $dbh->errstr . "\n"; +} + + +sub setup_engine() +{ + my ($engine)= @_; + my ($sth,$query); + + if (!$opt_mysql) + { + # Set variables that may interfere with timings + $query= "set global $engine.optimizer_disk_read_ratio=0"; + $sth= $dbh->do($query) || + die "Got error on '$query': " . $dbh->errstr . "\n"; + } +} + +sub create_seq_table +{ + my $name= "seq_1_to_$opt_rows"; + my $i; + print "Creating $name\n"; + $dbh->do("drop table if exists $name") || + die "Error on drop: " . $dbh->errstr ."\n"; + $dbh->do("create table $name (seq int(11) not null) engine=heap") + || die "Error on create: " . $dbh->errstr ."\n"; + for ($i= 1 ; $i < $opt_rows ; $i+=10) + { + $dbh->do("insert into $name values + ($i),($i+1),($i+2),($i+3),($i+4),($i+5),($i+6),($i+7),($i+8),($i+9)") || die "Error on insert"; + } +} + + + +############################################################################## +# Query functions +############################################################################## + +# Calculate the cost of the WHERE clause + +sub table_scan_without_where() +{ + my ($query_id)= @_; + return run_query($test_names[$query_id], + "table_scan", "ALL", $opt_rows, +"select sum(l_quantity) from $table"); +} + +sub table_scan_with_where() +{ + my ($query_id)= @_; + return run_query($test_names[$query_id], + "table_scan", "ALL", $opt_rows, +"select sum(l_quantity) from $table where l_commitDate >= '2000-01-01' and l_tax >= 0.0"); +} + +sub table_scan_with_where_no_match() +{ + my ($query_id)= @_; + return run_query($test_names[$query_id], + "table_scan", "ALL", $opt_rows, +"select sum(l_quantity) from $table where l_commitDate >= '2000-01-01' and l_tax > 0.0 /* NO MATCH */"); +} + + +sub table_scan_with_complex_where() +{ + my ($query_id)= @_; + return run_query($test_names[$query_id], + "table_scan", "ALL", $opt_rows, +"select sum(l_quantity) from $table where l_commitDate >= '2000-01-01' and l_quantity*l_extendedprice-l_discount+l_tax > 0.0"); +} + +# Calculate the time spent for table accesses (done with analyze statment) + +# Table scan + +sub table_scan_without_where_analyze() +{ + my ($query_id)= @_; + return run_query_with_analyze($test_names[$query_id], + "table_scan", "ALL", $opt_rows, +"select sum(l_quantity) from $table"); +} + +# Index scan with 2 key parts + +sub index_scan() +{ + my ($query_id)= @_; + return 0 if (!$has_force_index); + my ($query_id)= @_; + return run_query_with_analyze($test_names[$query_id], + "index_scan", "index", $opt_rows, +"select count(*) from $table force index (l_suppkey) where l_suppkey >= 0 and l_partkey >=0"); +} + +# Index scan with 2 key parts +# This is to check how the number of key parts affects the timeings + +sub index_scan_4_parts() +{ + my ($query_id)= @_; + return 0 if (!$has_force_index); + return run_query_with_analyze($test_names[$query_id], + "index_scan_4_parts", "index", $opt_rows, +"select count(*) from $table force index (long_suppkey) where l_linenumber >= 0 and l_extra >0"); +} + +sub range_scan() +{ + my ($query_id)= @_; + return 0 if (!$has_force_index); + return run_query_with_analyze($test_names[$query_id], + "range_scan", "range", $opt_rows, +"select sum(l_orderkey) from $table force index(l_suppkey) where l_suppkey >= 0 and l_partkey >=0 and l_discount>=0.0"); +} + +sub eq_ref_index_join() +{ + my ($query_id)= @_; + return run_query_with_analyze($test_names[$query_id], + "eq_ref_index_join", "eq_ref", 1, +"select straight_join count(*) from seq_1_to_$opt_rows,$table where seq=l_linenumber"); +} + +sub eq_ref_clustered_join() +{ + my ($query_id)= @_; + return run_query_with_analyze($test_names[$query_id], + "eq_ref_cluster_join", "eq_ref", 1, +"select straight_join count(*) from seq_1_to_$opt_rows,$table where seq=l_orderkey"); +} + +sub eq_ref_join() +{ + my ($query_id)= @_; + return run_query_with_analyze($test_names[$query_id], + "eq_ref_join", "eq_ref", 1, +"select straight_join count(*) from seq_1_to_$opt_rows,$table where seq=l_linenumber and l_partkey >= 0"); +} + +sub eq_ref_join_btree() +{ + my ($query_id)= @_; + return run_query_with_analyze($test_names[$query_id], + "eq_ref_btree", "eq_ref", 1, +"select straight_join count(*) from seq_1_to_$opt_rows,$table where seq=l_extra and l_partkey >= 0"); +} + + +# Calculate the cost of a basic where clause +# This can be used to find out the speed of the current computer compared +# to the reference computer on which the costs where calibrated. + +sub get_where_cost() +{ + my ($loop); + $loop=10000000; + # Return time in microseconds for one where (= optimizer_where_cost) + return query_time("select benchmark($loop, l_commitDate >= '2000-01-01' and l_tax >= 0.0) from $table limit 1")/$loop; +} + + +# Run a query to be able to calculate the costs of filter + +sub cost_of_filtering() +{ + my ($query, $cost1, $cost2); + do_query("set \@\@max_rowid_filter_size=10000000," . + "optimizer_switch='rowid_filter=on',". + "\@\@optimizer_scan_setup_cost=1000000"); + do_query("set \@old_cost=\@\@aria.OPTIMIZER_ROW_LOOKUP_COST"); + do_query("set global aria.OPTIMIZER_ROW_LOOKUP_COST=1"); + do_query("flush tables"); + $cost1= run_query_with_analyze("range", "range", "range", 500000, + "select count(l_discount) from check_costs_aria as t1 where t1.l_orderkey between 1 and 500000"); + $cost2= run_query_with_analyze("range-all", "range-all", "range|filter", 500000, + "select count(l_discount) from check_costs_aria as t1 where t1.l_orderkey between 1 and 500000 and l_linenumber between 1 and 500000"); + $cost3= run_query_with_analyze("range-none","range-none", "range|filter", 500000, + "select count(l_discount) from check_costs_aria as t1 where t1.l_orderkey between 1 and 500000 and l_linenumber between 500000 and 1000000"); + do_query("set global aria.OPTIMIZER_ROW_LOOKUP_COST=\@old_cost"); + do_query("flush tables"); + print_costs("range", $cost1); + print_costs("filter-all", $cost2); + print_costs("filter-none", $cost3); +} + +sub gprof_cost_of_filtering() +{ + $cost2= run_query_with_analyze("gprof","range-all", "range|filter", 500000, + "select count(l_discount) from check_costs_aria as t1 where t1.l_orderkey between 1 and 500000 and l_linenumber between 1 and 500000"); +} + + +############################################################################### +# Help functions for running the queries +############################################################################### + + +# Run query and return time for query in microseconds + +sub query_time() +{ + my ($query)= @_; + my ($start_time,$end_time,$time,$ms,$sth,$row); + + $start_time= new Benchmark; + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n"; + $end_time=new Benchmark; + $row= $sth->fetchrow_arrayref(); + $sth=0; + + $time= timestr(timediff($end_time, $start_time),"nop"); + $time =~ /([\d.]*)/; + return $1*1000000.0; +} + +# +# Run a query and compare the clock time +# + +sub run_query() +{ + my ($full_name, $name, $type, $expected_rows, $query)= @_; + my ($start_time,$end_time,$sth,@row,%res,$i,$optimizer_rows); + my ($extra, $last_type, $adjust_cost, $ms); + $adjust_cost=1.0; + + print "Timing full query: $full_name\n$query\n"; + + $sth= $dbh->prepare("explain $query") || die "Got error on 'explain $query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on 'explain $query': " . $dbh->errstr . "\n"; + + print "explain:\n"; + while ($row= $sth->fetchrow_arrayref()) + { + print $row->[0]; + for ($i= 1 ; $i < @$row; $i++) + { + print " " . $row->[$i] if (defined($row->[$i])); + } + print "\n"; + + $extra= $row->[@$row-1]; + $last_type= $row->[3]; + $optimizer_rows= $row->[8]; + } + if ($last_type ne $type && + ($type ne "index" || !($extra =~ /Using index/))) + { + print "Warning: Wrong scan type: '$last_type', expected '$type'\n"; + } + + if ($expected_rows >= 0 && + (abs($optimizer_rows - $expected_rows)/$expected_rows) > 0.1) + { + printf "Warning: Expected $expected_rows instead of $optimizer_rows from EXPLAIN. Adjusting costs\n"; + $adjust_cost= $expected_rows / $optimizer_rows; + } + + # Do one query to fill the cache + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n"; + $end_time=new Benchmark; + $row= $sth->fetchrow_arrayref(); + $sth=0; + + # Run query for real + $start_time= new Benchmark; + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n"; + $end_time=new Benchmark; + $row= $sth->fetchrow_arrayref(); + $sth=0; + + $time= timestr(timediff($end_time, $start_time),"nop"); + $time =~ /([\d.]*)/; + $ms= $1*1000.0; + + $query= "show status like 'last_query_cost'"; + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n";; + $row= $sth->fetchrow_arrayref(); + $sth=0; + $cost= $row->[1] * $adjust_cost; + printf "%10s time: %10.10s ms cost: %6.4f", $name, $ms, $cost; + if ($adjust_cost != 1.0) + { + printf " (was %6.4f)", $row->[1]; + } + print "\n\n"; + + $res{'cost'}= $cost; + $res{'time'}= $ms; + return \%res; +} + +# +# Run a query and compare the table access time from analyze statement +# The cost works for queries with one or two tables! +# + +sub run_query_with_analyze() +{ + my ($full_name,$name, $type, $expected_rows, $query)= @_; + my ($start_time,$end_time,$sth,@row,%res,$i,$j); + my ($optimizer_rows, $optimizer_rows_first); + my ($adjust_cost, $ms, $second_ms, $analyze, $local_where_cost); + my ($extra, $last_type, $tot_ms, $found_two_tables); + + $found_two_tables= 0; + $adjust_cost=1.0; + if (!$opt_mysql) + { + $local_where_cost= $where_cost/1000 * $opt_rows; + } + else + { + $local_where_cost= $where_cost * $opt_rows; + } + $optimizer_rows_first= undef; + + print "Timing table access for query: $full_name\n$query\n"; + + $sth= $dbh->prepare("explain $query") || die "Got error on 'explain $query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on 'explain $query': " . $dbh->errstr . "\n"; + + print "explain:\n"; + if (!$opt_mysql) + { + $type_pos= 3; + $row_pos= 8; + } + else + { + $type_pos= 4; + $row_pos= 9; + } + + $j= 0; + while ($row= $sth->fetchrow_arrayref()) + { + $j++; + print $row->[0]; + for ($i= 1 ; $i < @$row; $i++) + { + print " " . $row->[$i] if (defined($row->[$i])); + # print " X" if (!defined($row->[$i])); + } + print "\n"; + + $extra= $row->[@$row-1]; + $last_type= $row->[$type_pos]; + if (!defined($optimizer_rows_first)) + { + $optimizer_rows_first= $row->[$row_pos]; + } + $optimizer_rows= $row->[$row_pos]; + } + $found_two_tables= 1 if ($j > 1); + + if ($last_type ne $type && + ($type ne "index" || !($extra =~ /Using index/))) + { + print "Warning: Wrong scan type: '$last_type', expected '$type'\n"; + } + if ($expected_rows >= 0 && + (abs($optimizer_rows - $expected_rows)/$expected_rows) > 0.1) + { + printf "Warning: Expected $expected_rows instead of $optimizer_rows from EXPLAIN. Adjusting costs\n"; + $adjust_cost= $expected_rows / $optimizer_rows; + } + + # Do one query to fill the cache + if (!defined($opt_grof)) + { + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n"; + $row= $sth->fetchrow_arrayref(); + $sth=0; + } + + # Run the query through analyze statement + $tot_ms=0; + if (!$opt_mysql) + { + for ($i=0 ; $i < $opt_test_runs ; $i++) + { + my ($j); + $sth= $dbh->prepare("analyze format=json $query" ) || die "Got error on 'analzye $query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n"; + $row= $sth->fetchrow_arrayref(); + $analyze= $row->[0]; + $sth=0; + + # Fetch the timings + $j=0; + while ($analyze =~ /r_table_time_ms": ([0-9.]*)/g) + { + $tot_ms= $tot_ms+ $1; + $j++; + } + if ($j > 2) + { + die "Found too many tables, program needs to be extended!" + } + # Add cost of filtering + while ($analyze =~ /r_filling_time_ms": ([0-9.]*)/g) + { + $tot_ms= $tot_ms+ $1; + } + } + } + else + { + my $local_table= substr($table,index($table,".")+1); + for ($i=0 ; $i < $opt_test_runs ; $i++) + { + my ($j); + $sth= $dbh->prepare("explain analyze $query" ) || die "Got error on 'analzye $query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n"; + $row= $sth->fetchrow_arrayref(); + $analyze= $row->[0]; + $sth=0; + } + # Fetch the timings + $j=0; + + if ($analyze =~ / $local_table .*actual time=([0-9.]*) .*loops=([0-9]*)/g) + { + my $times= $1; + my $loops= $2; + $times =~ /\.\.([0-9.]*)/; + $times= $1; + $times="0.005" if ($times == 0); + #print "time: $times \$1: $1 loops: $loops\n"; + $tot_ms= $tot_ms+ $times*$loops; + $j++; + } + if ($j > 1) + { + die "Found too many tables, program needs to be extended!" + } + } + + + if ($found_two_tables) + { + # Add the cost of the where for the two tables. The last table + # is assumed to have $expected_rows while the first (driving table) + # may have less rows. Take that into account when calculalting the + # total where cost. + $local_where_cost= ($local_where_cost + + $local_where_cost * + ($optimizer_rows_first/$opt_rows)); + } + $ms= $tot_ms/$opt_test_runs; + + if ($opt_analyze) + { + print "\nanalyze:\n" . $analyze . "\n\n"; + } + + if (!defined($opt_grof)) + { + # Get last query cost + $query= "show status like 'last_query_cost'"; + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n";; + $row= $sth->fetchrow_arrayref(); + $sth=0; + $cost= $row->[1] * $adjust_cost; + + printf "%10s time: %10.10s ms cost-where: %6.4f cost: %6.4f", + $name, $ms, $cost - $local_where_cost, $cost; + if ($adjust_cost != 1.0) + { + printf " (cost was %6.4f)", $row->[1]; + } + } + else + { + printf "%10s time: %10.10s ms", $name, $ms; + $cost= 0; $local_where_cost= 0; + } + print "\n\n"; + + $res{'cost'}= $cost; + $res{'where_cost'}= $local_where_cost; + $res{'time'}= $ms; + return \%res; +} + + +sub do_query() +{ + my ($query)= @_; + $dbh->do($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; +} + + +sub print_totals() +{ + my ($i, $j); + print "Totals per test\n"; + for ($j= $where_tests+1 ; $j <= $#test_names; $j++) + { + print "$test_names[$j]:\n"; + for ($i= $0 ; $i <= $#engines ; $i++) + { + if ($res[$i][$j]) + { + my $cost= $res[$i][$j]->{'cost'} - $res[$i][$j]->{'where_cost'}; + my $ms= $res[$i][$j]->{'time'}; + printf "%-8s %10.4f ms cost: %10.4f cost/time: %8.4f\n", + $engines[$i], $ms, $cost, $cost/$ms; + } + } + } +} + + +# This function can be used to test things with gprof + +sub test_with_gprof() +{ + my ($function_ref, $loops)= @_; + my ($sum, $i, $cost); + + printf "Running test $function_ref $loops time\n"; + $sum= 0; $loops=10; + for ($i=0 ; $i < $loops ; $i++) + { + $cost= $function_ref->(); + $sum+= $cost->{'time'}; + } + print "Average: " . ($sum/$loops) . "\n"; + print "Shuting down server\n"; + $dbh->do("shutdown") || die "Got error .."; +} + +############################################################################## +# Get various simple data from MariaDB +############################################################################## + +sub print_mariadb_version() +{ + my ($query, $sth, $row); + $query= "select VERSION()"; + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; +$sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n";; + $row= $sth->fetchrow_arrayref(); + print "Server: $row->[0]"; + + $query= "show variables like 'VERSION_SOURCE_REVISION'"; + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; +$sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n";; + $row= $sth->fetchrow_arrayref(); + print " Commit: $row->[1]\n"; +} + + +sub get_row_count() +{ + $query= "select count(*) from $table"; + $sth= $dbh->prepare($query) || die "Got error on '$query': " . $dbh->errstr . "\n"; + if (!$sth->execute) + { + if (!($dbh->errstr =~ /doesn.*exist/)) + { + die "Got error on '$query': " . $dbh->errstr . "\n"; + } + return 0; + } + $row= $sth->fetchrow_arrayref(); + return $row->[0]; +} + + +sub get_variable() +{ + my ($name)= @_; + $query= "select @@" . $name; + if (!($sth= $dbh->prepare($query))) + { + die "Got error on '$query': " . $dbh->errstr . "\n"; + } + $sth->execute || die "Got error on '$query': " . $dbh->errstr . "\n";; + $row= $sth->fetchrow_arrayref(); + return $row->[0]; +}