Задавайте вопросы, мы ответим
Вы не зашли.
Акутогава-сан, прошу простить мне косноязычность!
У нас есть исходный набор данных:
Неактивен
Вася, ну за час можно разобраться. Но надо все-таки сделать пример нагляднее. Первое - убрать инициализацию из запроса, пусть это будет два запроса, как положено по мануалу. И еще - бага в слове <cache> в extended explain, это понятнее, чем результат запроса. И нужно привести результат для разных версий, включая EXPLAIN EXTENDED - есть шанс, что это будет понято (так как разный результат = бага в одной из версий).
Неактивен
И еще - переменная @n ведь не нужна? Лучше сократить число переменных.
Неактивен
От ее использования можно отказаться, да.
Заменив
and @i<@n
на
and @i<1
И еще сузить область поиска можно было бы заменив login на числовое поле вместо текстового.
Ибо напомню, что в инструкции
or (@l:=login) or 1
or 1
неспроста было добавлено.
Неактивен
deadka написал:
И еще сузить область поиска можно было бы заменив login на числовое поле вместо текстового.
Ибо напомню, что в инструкции
or (@l:=login) or 1
or 1
неспроста было добавлено.
Всё-таки поклеп
У меня в последних примерах как раз по этой причине и был логин числом, потому как про условие (.. or 1) действительно можно заранее сказать, что это всегда истина.
Неактивен
Предлагаю такой вариант.
MySQL 5.0 написал:
mysql> set @i:=0, @p:=-999;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test where if(@p=a,@i:=@i+1,(@i:=0) or (@p:=a)) and @i<1;
+------+------+
| a | b |
+------+------+
| -2 | 1 |
| -1 | 1 |
| 1 | 1 |
+------+------+
3 rows in set (0.00 sec)
mysql> explain extended select * from test where if(@p=a,@i:=@i+1,(@i:=0) or (@p :=a)) and @i<1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: index
possible_keys: NULL
key: a
key_len: 10
ref: NULL
rows: 6
Extra: Using where; Using index
1 row in set, 1 warning (0.01 sec)
mysql> show warnings\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: select `test`.`test`.`a` AS `a`,`test`.`test`.`b` AS `b` from `test`.`t est` where (if(((@p) = `test`.`test`.`a`),(@i:=((@i) + 1)),((@i:=0) or (@p:=`tes t`.`test`.`a`))) and ((@i) < 1))
1 row in set (0.00 sec)
5.5.34-MariaDB-log
MariaDB 5.5 написал:
MariaDB [test]> set @i:=0, @p:=-999;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> select * from test where if(@p=a,@i:=@i+1,(@i:=0) or (@p:=a)) an
d @i<1;
+------+------+
| a | b |
+------+------+
| -2 | 1 |
+------+------+
1 row in set (0.00 sec)
MariaDB [test]> explain extended select * from test where if(@p=a,@i:=@i+1,(@i:=
0) or (@p:=a)) and @i<1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: index
possible_keys: NULL
key: a
key_len: 10
ref: NULL
rows: 6
filtered: 100.00
Extra: Using where; Using index
1 row in set, 1 warning (0.00 sec)
MariaDB [test]> show warnings\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: select `test`.`test`.`a` AS `a`,`test`.`test`.`b` AS `b` from `test`.`t
est` where (if(((@`p`) = `test`.`test`.`a`),(@i:=((@`i`) + 1)),(<cache>((@i:=0))
or (@p:=`test`.`test`.`a`))) and ((@`i`) < 1))
1 row in set (0.00 sec)
Из примера видно, что запрос в разных версиях дает разный результат и в случае MariaDB 5.5 сервер закэшировал выражение <cache>((@i:=0))
or (@p:=`test`.`test`.`a`)) при первом вичислении. Это ошибка так как результат данного выражения зависит от значения поля `a`.
Результат присвоения нуля пользовательской переменной будет false, а любого целого числа true
Неактивен
http://sqlfiddle.com/#!2/d8e10/1
Как и ожидалось в MySQL5.5 бага присутствует. show warnings сервис не показывает, но вывод можно сделать на основании результата выполнения самого запроса.
Кстати, удобный сервис для проверки запроса в разных версиях, правда из MySQL там только 5.1, 5.5, 5.6
Возвращаясь к началу темы, в 5.6 from-подзапрос не ликвидируется как не существенный. Эту оптимизацию в MySQL ещё не ввели.
Неактивен
Наверное надо Монти сообщить о баге https://mariadb.com/kb/en/reporting-bugs/ и на bugs.mysql.com
Неактивен