2017-01-28 9 views
0

Если я выполнить запрос напримерMysql оптимизации подзапросов в пункте, где

SELECT * 
FROM `table1` 
WHERE 1 OR EXISTS (
        SELECT show 
        FROM `table2` 
        WHERE id IN(1,2,3) 
       ) 

Я ожидал бы оптимизатору, чтобы понять, что где положение ВСЕГДА решает верно, и что поэтому нет необходимости запускать подзапрос. Поскольку выполнение запроса с помощью EXPLAIN показывает, что это не так, и подзапрос выполняется в любом случае. Это сужен пример более сложной проблемы, где я судимое выполнять различные подзапросов базы на значении столбца внешнего запроса, как:

SELECT value FROM table t 
LEFT JOIN... 
WHERE 
(SELECT 
    IF(t.value = 1, 
     (SELECT ...), 
     (SELECT ...) 
    ) 
) 

The интенсионала было то, что только один из колб подзапросов в ГДЕ условие выполняется, но то же самое происходит здесь, оба выполняются, но используется только одно значение. Таким образом, результат правильный, но запускаются бесполезные запросы. Я попробовал CASE WHEN, а также такую ​​же проблему. Не уверен, что это потому, что я использую MariaDB или что-то, что мне здесь не хватает.

+0

Пожалуйста, укажите номер версии MariaDB, которые вы используете. И, пожалуйста, предоставьте 'EXPLAIN SELECT ...'. –

+0

Аналогичный запрос не может «закоротить» в 5.6.22. –

+0

Ditto for 5.7.15, 8.0.0 и MariaDB 10.2.2. –

ответ

0

Извините, я надеюсь, что правильно понимаю ваш вопрос. В первом запросе с WHERE 1 MySQL НИКОГДА не выполняет подзапрос EXISTS. EPLAIN покажет вам, что можно сделать. Вы можете видеть это просто с SHOW status LIKE 'Handler_read_first'; У меня есть 2 стола. если я проверить с тем, где 1 единственное его приращение на 1 (1 табл чтения) и без него увеличивается на 2

образца

таблицы

MariaDB [test]> select * from index_usage; 
+----+------+------+------+-------+ 
| id | a | b | c | dummy | 
+----+------+------+------+-------+ 
| 11 | 1 | 1 | 1 | a  | 
+----+------+------+------+-------+ 
1 row in set (0.00 sec) 

MariaDB [test]> select * from index_usage_copy; 
+----+------+------+------+-------+ 
| id | a | b | c | dummy | 
+----+------+------+------+-------+ 
| 99 | 1 | 1 | 1 | a  | 
+----+------+------+------+-------+ 
1 row in set (0.00 sec) 

счетчик

MariaDB [test]> SHOW status LIKE 'Handler_read_first'; 
+--------------------+-------+ 
| Variable_name  | Value | 
+--------------------+-------+ 
| Handler_read_first | 59 | 
+--------------------+-------+ 
1 row in set (0.00 sec) 

первый запрос (без WHERE 1) приращение на 2

MariaDB [test]> SELECT * from index_usage WHERE EXISTS (SELECT 1 FROM index_usage_copy where id in (1,2,99)); SHOW status LIKE 'Handler_read_first'; 
    +----+------+------+------+-------+ 
    | id | a | b | c | dummy | 
    +----+------+------+------+-------+ 
    | 11 | 1 | 1 | 1 | a  | 
    +----+------+------+------+-------+ 
    1 row in set (0.00 sec) 

    +--------------------+-------+ 
    | Variable_name  | Value | 
    +--------------------+-------+ 
    | Handler_read_first | 61 | 
    +--------------------+-------+ 
    1 row in set (0.00 sec) 

MariaDB [test]> SELECT * from index_usage WHERE EXISTS (SELECT 1 FROM index_usage_copy where id in (1,2,99)); SHOW status LIKE 'Handler_read_first'; 
+----+------+------+------+-------+ 
| id | a | b | c | dummy | 
+----+------+------+------+-------+ 
| 11 | 1 | 1 | 1 | a  | 
+----+------+------+------+-------+ 
1 row in set (0.00 sec) 

+--------------------+-------+ 
| Variable_name  | Value | 
+--------------------+-------+ 
| Handler_read_first | 63 | 
+--------------------+-------+ 
1 row in set (0.00 sec) 

MariaDB [test]> SELECT * from index_usage WHERE EXISTS (SELECT 1 FROM index_usage_copy where id in (1,2,99)); SHOW status LIKE 'Handler_read_first'; 
+----+------+------+------+-------+ 
| id | a | b | c | dummy | 
+----+------+------+------+-------+ 
| 11 | 1 | 1 | 1 | a  | 
+----+------+------+------+-------+ 
1 row in set (0.00 sec) 

+--------------------+-------+ 
| Variable_name  | Value | 
+--------------------+-------+ 
| Handler_read_first | 65 | 
+--------------------+-------+ 
1 row in set (0.00 sec) 

теперь с WHERE 1 - увеличивается только на один

MariaDB [test]> SELECT * from index_usage WHERE 1 OR EXISTS (SELECT 1 FROM index_usage_copy where id in (1,2,99)); SHOW status LIKE 'Handler_read_first'; 
+----+------+------+------+-------+ 
| id | a | b | c | dummy | 
+----+------+------+------+-------+ 
| 11 | 1 | 1 | 1 | a  | 
+----+------+------+------+-------+ 
1 row in set (0.00 sec) 

+--------------------+-------+ 
| Variable_name  | Value | 
+--------------------+-------+ 
| Handler_read_first | 66 | 
+--------------------+-------+ 
1 row in set (0.00 sec) 

MariaDB [test]> SELECT * from index_usage WHERE 1 OR EXISTS (SELECT 1 FROM index_usage_copy where id in (1,2,99)); SHOW status LIKE 'Handler_read_first'; 
+----+------+------+------+-------+ 
| id | a | b | c | dummy | 
+----+------+------+------+-------+ 
| 11 | 1 | 1 | 1 | a  | 
+----+------+------+------+-------+ 
1 row in set (0.00 sec) 

+--------------------+-------+ 
| Variable_name  | Value | 
+--------------------+-------+ 
| Handler_read_first | 67 | 
+--------------------+-------+ 
1 row in set (0.00 sec) 

MariaDB [test]> 
+0

, что объясняет это благодаря – bodycasino