Bug #41293 user variables from remote hosts can be considerably slow
| Submitted: | 8 Dec 2008 10:21 | Modified: | 14 Apr 2009 19:11 |
|---|---|---|---|
| Reporter: | Peter Laursen (Basic Quality Contributor) | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server | Severity: | S2 (Serious) |
| Version: | 5.0 bzr, 5.1 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | qc | ||
[8 Dec 2008 10:21]
Peter Laursen
[8 Dec 2008 12:08]
Valeriy Kravchuk
Thank you for a problem report. Please, send SHOW CREATE TABLE results for the table(s) used and EXPLAIN results for the queries with and without user variable.
[8 Dec 2008 12:10]
Martin Bruegemann
Hi, I'm the User having the bug... I tried executing the Query from Mysql Query Browser and from SQLyog Enterprise. Both show the same behaviour - with the use of Variable the Select statement seems to use no Index! I tried in on my replication-DB Server(Mysql 4.1.22-standard) with less Ram (Slower)- on a table with 1.1 Million Rows... Using no variable: (34 row(s) returned) Execution Time : 00:00:00:015 Using a variable in the same Statement: Execution Time : 00:00:52:234 This is over 52 Seconds slower! And repeating the Select statement whith the Variable over and over, there is no faster answer- Seems no Cache is being used... I just executed a Select Statement on the same server and table with no index being used, and this takes: Execution Time : 00:01:03:500
[8 Dec 2008 12:20]
Martin Bruegemann
Create Table Statement
Attachment: Create Statement.txt (text/plain), 10.23 KiB.
[8 Dec 2008 12:22]
Peter Laursen
wiht my example
EXPLAIN select * from hugetable where col9 = '2014-06-08 00:00:00';
/*
id select_type table type possible_keys key key_len ref rows Extra
------ ----------- --------- ------ ------------- ------ ------- ------ ------ -----------
1 SIMPLE hugetable ALL (NULL) (NULL) (NULL) (NULL) 51311 Using where
*/
set @constant = '2014-06-08 00:00:00';
EXPLAIN select * from hugetable where col9 = @constant;
/*
id select_type table type possible_keys key key_len ref rows Extra
------ ----------- --------- ------ ------------- ------ ------- ------ ------ -----------
1 SIMPLE hugetable ALL (NULL) (NULL) (NULL) (NULL) 51311 Using where
*/
(the table in this example has no indexes)
[8 Dec 2008 12:24]
Martin Bruegemann
set @doc = '40803231'; Explain Select * from IASSALITEM where client = '00' and company = '01' and doctype = 'GR' and docnum = @doc ; "1" "SIMPLE" "IASSALITEM" "ref" "IASSALITEM_10,IASSALITEM_4,IASSALITEM_5,IASSALITEM_6,IASSSALITEM_R1,CLIENT,IASSALITEM_CUST_MAT,IASSALITEM_3" "IASSALITEM_5" "7" "const,const,const" "392600" "Using where" Explain Select * from IASSALITEM where client = '00' and company = '01' and doctype = 'GR' and docnum = '40803231'; "1" "SIMPLE" "IASSALITEM" "range" "IASSALITEM_U1,IASSALITEM_1,IASSALITEM_10,IASSALITEM_4,IASSALITEM_5,IASSALITEM_6,IASSSALITEM_R1,CLIENT,IASSALITEM_CUST_MAT,IASSALITEM_3" "IASSALITEM_U1" "8" \N "42" "Using where"
[8 Dec 2008 12:25]
Martin Bruegemann
The Create Statement was too big, you ca find it under "Files" Martin
[8 Dec 2008 13:09]
Peter Laursen
btw: I wonder if 5.0/5.1 SHOW PROFILE can be used to get additional info about this!
[2 Apr 2009 21:59]
Sveta Smirnova
Thank you for the report.
20% decrease verified as described.
Test used:
drop table if exists t1;
create table t1(f1 int not null auto_increment primary key, f2 text);
insert into t1 (f2) values('fdsfdsfdsfdsfsdfdsfdsfdsfdsfdsfdsfds');
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
insert into t1 (f2) select f2 from t1;
delimiter |
drop procedure if exists p1|
create procedure p1(v1 INT)
begin
set @var = v1;
SET @x = 0;
REPEAT
select f1, f2 into @dummy1, @dummy2 from t1 where f1 = @var;
SET @x = @x + 1;
UNTIL @x > 10000 END REPEAT;
end
|
call p1(10)|
Results with 5.0.
Local:
mysql> call p1(10);
Query OK, 0 rows affected (2.98 sec)
mysql> call p1(10);
Query OK, 0 rows affected (2.97 sec)
mysql> call p1(10);
Query OK, 0 rows affected (2.97 sec)
mysql> call p1(10);
Query OK, 0 rows affected (2.96 sec)
Remote:
mysql> call p1(10);
Query OK, 0 rows affected (3.40 sec)
mysql> call p1(10);
Query OK, 0 rows affected (3.26 sec)
mysql> call p1(10);
Query OK, 0 rows affected (3.26 sec)
mysql> call p1(10);
Query OK, 0 rows affected (3.26 sec)
mysql> call p1(10);
Query OK, 0 rows affected (3.41 sec)
[14 Apr 2009 18:51]
Sveta Smirnova
Results for TCP/IP and socket on the same machine are identical:
master [localhost] {msandbox} (test) > call p1(10);
Query OK, 0 rows affected (0.57 sec)
master [localhost] {msandbox} (test) > call p1(10);
Query OK, 0 rows affected (0.57 sec)
master [localhost] {msandbox} (test) > call p1(10);
Query OK, 0 rows affected (0.56 sec)
master [localhost] {msandbox} (test) > call p1(10);
Query OK, 0 rows affected (0.56 sec)
master [localhost] {msandbox} (test) > call p1(10);
Query OK, 0 rows affected (0.56 sec)
[14 Apr 2009 19:00]
Sveta Smirnova
For remote host results are larger: mysql> call p1(10); Query OK, 0 rows affected (0.79 sec) mysql> call p1(10); Query OK, 0 rows affected (0.62 sec) mysql> call p1(10); Query OK, 0 rows affected (0.62 sec) mysql> call p1(10); Query OK, 0 rows affected (0.62 sec) mysql> call p1(10); Query OK, 0 rows affected (2.39 sec)
[14 Apr 2009 19:04]
Sveta Smirnova
Same if reduce using of user variables:
drop procedure if exists p2|
create procedure p2(v1 INT)
begin
declare x int;
declare dummy1, dummy2 varchar(255);
set @var = v1;
SET x = 0;
REPEAT
select f1, f2 into dummy1, dummy2 from t1 where f1 = @var;
SET x = x + 1;
UNTIL x > 10000 END REPEAT;
end
|
Local (both tcp and socket):
master [localhost] {root} (test) > call p2(10);
Query OK, 0 rows affected (0.52 sec)
master [localhost] {root} (test) > call p2(10);
Query OK, 0 rows affected (0.52 sec)
master [localhost] {root} (test) > call p2(10);
Query OK, 0 rows affected (0.52 sec)
Remote:
mysql> call p2(10);
Query OK, 0 rows affected (0.58 sec)
mysql> call p2(10);
Query OK, 0 rows affected (0.76 sec)
mysql> call p2(10);
Query OK, 0 rows affected (0.71 sec)
mysql> call p2(10);
Query OK, 0 rows affected (0.61 sec)
mysql> call p2(10);
Query OK, 0 rows affected (0.78 sec)
mysql> call p2(10);
Query OK, 0 rows affected (0.79 sec)
[14 Apr 2009 19:11]
Sveta Smirnova
Same with index:
alter table t1 add index ind1(f2(100));
Local:
master [localhost] {root} (test) > call p1(10);
Query OK, 0 rows affected (0.58 sec)
master [localhost] {root} (test) > call p1(10);
Query OK, 0 rows affected (0.57 sec)
master [localhost] {root} (test) > call p1(10);
Query OK, 0 rows affected (0.57 sec)
master [localhost] {root} (test) > call p1(10);
Query OK, 0 rows affected (0.57 sec)
master [localhost] {root} (test) > call p2(10);
Query OK, 0 rows affected (0.52 sec)
master [localhost] {root} (test) > call p2(10);
Query OK, 0 rows affected (0.52 sec)
master [localhost] {root} (test) > call p2(10);
Query OK, 0 rows affected (0.52 sec)
Remote:
mysql> call p1(10);
Query OK, 0 rows affected (0.75 sec)
mysql> call p1(10);
Query OK, 0 rows affected (0.76 sec)
mysql> call p1(10);
Query OK, 0 rows affected (0.68 sec)
mysql> call p2(10);
Query OK, 0 rows affected (0.60 sec)
mysql> call p2(10);
Query OK, 0 rows affected (0.77 sec)
mysql> call p2(10);
Query OK, 0 rows affected (0.76 sec)
[14 Apr 2009 19:23]
Sveta Smirnova
Additional tests:
create procedure p3(v1 INT)
begin
declare x int;
declare dummy1, dummy2 varchar(255);
SET x = 0;
REPEAT
select f1, f2 into dummy1, dummy2 from t1 where f1 = v1;
SET x = x + 1;
UNTIL x > 10000 END REPEAT;
end
|
drop procedure if exists p4|
create procedure p4(v1 INT)
begin
declare x int;
SET x = 0;
REPEAT
set @var='fdsfdsfdsfdsfsdfdsfdsfdsfdsfdsfdsfds';
SET x = x + 1;
UNTIL x > 10000 END REPEAT;
end
|
Local:
master [localhost] {root} (test) > call p3(10);
Query OK, 0 rows affected (0.52 sec)
master [localhost] {root} (test) > call p3(10);
Query OK, 0 rows affected (0.52 sec)
master [localhost] {root} (test) > call p3(10);
Query OK, 0 rows affected (0.52 sec)
master [localhost] {root} (test) > call p3(10);
Query OK, 0 rows affected (0.52 sec)
master [localhost] {root} (test) > call p4(10);
Query OK, 0 rows affected (0.17 sec)
master [localhost] {root} (test) > call p4(10);
Query OK, 0 rows affected (0.16 sec)
master [localhost] {root} (test) > call p4(10);
Query OK, 0 rows affected (0.17 sec)
master [localhost] {root} (test) > call p4(10);
Query OK, 0 rows affected (0.17 sec)
Same with tcp and socket
Remote:
mysql> call p3(10);
Query OK, 0 rows affected (0.66 sec)
mysql> call p3(10);
Query OK, 0 rows affected (0.72 sec)
mysql> call p3(10);
Query OK, 0 rows affected (0.73 sec)
mysql> call p4(10);
Query OK, 0 rows affected (0.23 sec)
mysql> call p4(10);
Query OK, 0 rows affected (0.24 sec)
mysql> call p4(10);
Query OK, 0 rows affected (0.23 sec)
[9 Oct 11:58]
Shane Bester
Probably not a bug. It's likely RTT times. See also: https://bugs.mysql.com/bug.php?id=115646
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.071 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.