Chukcha

Рейтинг
291
Регистрация
04.02.2005

Вот эта штука

LEFT JOIN tables4_address AS t4 ON t1.id = t4.item_id

WHERE
(t4.geo_long BETWEEN 45.161317 AND 45.181317) AND
(t4.geo_lat BETWEEN 54.181330999996 AND 54.201330999996)

Автоматически трансформируется в INNER JOIN (LEFT JOIN вырождается в INNER

JOIN tables4_address AS t4 ON t1.id = t4.item_id

WHERE
(t4.geo_long BETWEEN 45.161317 AND 45.181317) AND
(t4.geo_lat BETWEEN 54.181330999996 AND 54.201330999996)

Но здесь вопрос к "оптимизатору"

И здесь, судя по всему, основное время - это построение плана запроса, и для LEFT он может оказаться проще. Такое встречается и на простейших запросах.

после этого можете еще поэкспериментировать с заменой каждого BETWEEN на два условия "больше" и "меньше",

https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_between

This is equivalent to the expression (min <= expr AND expr <= max)

но там есть оговорка о типах данных

---------- Добавлено 25.09.2017 в 22:35 ----------

Dram:
Составной индекс по гео лат-лонг уже есть

А зачем? Чисто теоретически ? Индекс по real?

---------- Добавлено 25.09.2017 в 23:02 ----------

Объяснить такое поведение можно

У вас есть маленькая таблица, и индекс..

Индекс это дерево (туда-сюда) (перемещение по разным частям таблицы)

А таблица - (fullsscan) - только туда (последовательное чтение)

Вот оптимизатор и выбрал оптимальное решение

сделать optimaze и analyze

И проверить

Sitealert:
А что значит "некорректно"?

SELECT p.product_id, pd.name

FROM oc_product_description pd
LEFT JOIN oc_product p ON p.product_id = pd.product_id
AND pd.language_id =1

13,698 всего

 product_id 	name

35 Product 8
48 iPod Classic
NULL iPhone
28 HTC Touch HD
44 MacBook Air
45 MacBook Pro
29 Palm Treo Pro
36 iPod Nano
46 Sony VAIO
47 HP LP3065
32 iPod Touch
41 iMac
33 Samsung SyncMaster 941BW
34 iPod Shuffle
43 MacBook
31 Nikon D300
49 Samsung Galaxy Tab 10.1
42 Apple Cinema 30&quot;
30 Canon EOS 5D
NULL Product 8

SELECT COUNT( product_id )

FROM oc_product_description pd

COUNT(product_id)

13698

SELECT p.product_id, pd.name

FROM oc_product p
JOIN oc_product_description pd ON p.product_id = pd.product_id
AND pd.language_id =1

4,566 всего

SELECT COUNT(*) FROM oc_product p

COUNT(*)

4566

Я не знаю, почему

Но это запрос не должен работать!!!!

Может вы неверно его показываете?

Вот я пытался на своих данных


SELECT * FROM product p
JOIN pdroduct_description ON p.product_id = pd.product_id AND pd.langugae_id = 1

Это корректный запрос


SELECT * FROM product_description pd
LEFT JOIN product ON p.product_id = pd.product_id AND pd.langugae_id = 1

Запрос отработал некорректно. А ведь очень похож на ваш

Я мог бы понять это в секции WHERE, но в LEFT JOIN не понимаю

Если вам не сложно, дайте дамп этих таблиц

Да причем здесь сортировка, если второй запрос просто дикий


SELECT
t1.id, t1.created,
t1.description,
t2.title,
CONCAT_WS('-', t2.id, t2.alias) AS item_alias,
CONCAT_WS('-', t3.id, t3.alias) AS category_alias,
CONCAT_WS('-', t4.id, t4.alias) AS section_alias
FROM
table1 AS t1
LEFT JOIN
table2 AS t2 ON t1.object_id = t2.id AND t1.object_group = 'com_group'
LEFT JOIN
table3 AS t3 ON t2.category_id = t3.id
LEFT JOIN
table4 AS t4 ON t2.section_id = t4.id
ORDER BY t1.id DESC LIMIT 3;

А именно

table2 AS t2 ON t1.object_id = t2.id AND t1.object_group = 'com_group'

Я попытался сэмулировать запрос на своих тестовых данных

У меня такая хрень получилась...

очень странное поведение

даже по explain

во втором случае выбрано всего три строки

Поиметь бы дамп...

FROM table1 AS t1

INNER JOIN table2 AS t2 ON t1.object_id = t2.id'

FROM table2 AS t2

INNER JOIN table1 AS t1 ON t1.object_id = t2.id' AND t1.object_group = 'com_group'

Мабуть так

тут можно экспериментировать сколько угодно

SELECT t1.id, t1.created, t1.description, t2.title,

CONCAT_WS('-', t2.id, t2.alias) AS item_alias,
CONCAT_WS('-', t3.id, t3.alias) AS category_alias,
CONCAT_WS('-', t4.id, t4.alias) AS section_alias
FROM table1 AS t1
INNER JOIN table2 AS t2 ON t1.object_id = t2.id'
LEFT JOIN table3 AS t3 ON t2.category_id = t3.id
LEFT JOIN table4 AS t4 ON t2.section_id = t4.id
WHERE t1.object_group = 'com_group
ORDER BY t1.id DESC LIMIT 3;

Например меняем порядок таблиц

SELECT t1.id, t1.created, t1.description, t2.title,

CONCAT_WS('-', t2.id, t2.alias) AS item_alias,
CONCAT_WS('-', t3.id, t3.alias) AS category_alias,
CONCAT_WS('-', t4.id, t4.alias) AS section_alias
FROM table2 AS t2
INNER JOIN table1 AS t1 ON t2.object_id = t1.id' AND t1.object_group = 'com_group'
LEFT JOIN table3 AS t3 ON t2.category_id = t3.id
LEFT JOIN table4 AS t4 ON t2.section_id = t4.id

ORDER BY t1.id DESC LIMIT 3;


---------- Добавлено 23.09.2017 в 13:16 ----------

LEOnidUKG:
Я привёл информацию, что это разные инструменты и результаты будут разные. Просто так заменить слова и радоваться не получится.

Я вообще стараюсь избегать таких запросов, лучше несколько простых и перебор, чем вот такие конструкции и потом ищи гадай, что и зачем, почему это сжирает память и ещё по 4-6 секунд выполняется.

Та нормальный запрос, То вы, наверное не видели джойнов по 10 таблиц, и вложенных запросов.

Dram:
Меняем INNER на LEFT - результат запроса остается тот же, а время сокращается до 0,005

Но у вас и результат должен быть разный

1-й запрос != 2-му запросу


SELECT t1.id, t1.created, t1.description, t2.title,
CONCAT_WS('-', t2.id, t2.alias) AS item_alias,
CONCAT_WS('-', t3.id, t3.alias) AS category_alias,
CONCAT_WS('-', t4.id, t4.alias) AS section_alias
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t1.object_id = t2.id AND t1.object_group = 'com_group'
LEFT JOIN table3 AS t3 ON t2.category_id = t3.id
LEFT JOIN table4 AS t4 ON t2.section_id = t4.id
ORDER BY t1.id DESC LIMIT 3;

Не стесняйтесь - показывайте реальные названия таблиц и колонок

Так проще понять и связи и остальное

Потому что первый вообще какой-то "левый"


SELECT t1.id, t1.created, t1.description, t2.title,
CONCAT_WS('-', t2.id, t2.alias) AS item_alias,
CONCAT_WS('-', t3.id, t3.alias) AS category_alias,
CONCAT_WS('-', t4.id, t4.alias) AS section_alias
FROM table1 AS t1
INNER JOIN table2 AS t2 ON t1.object_id = t2.id AND t1.object_group = 'com_group'
LEFT JOIN table3 AS t3 ON t2.category_id = t3.id
LEFT JOIN table4 AS t4 ON t2.section_id = t4.id
ORDER BY t1.id DESC LIMIT 3;

за счет

INNER JOIN table2 AS t2 ON t1.object_id = t2.id AND t1.object_group = 'com_group'

ЗАчем? если t1.object_group не в видимости t2

Может Вам нужен


SELECT t1.id, t1.created, t1.description, t2.title,
CONCAT_WS('-', t2.id, t2.alias) AS item_alias,
CONCAT_WS('-', t3.id, t3.alias) AS category_alias,
CONCAT_WS('-', t4.id, t4.alias) AS section_alias
FROM table1 AS t1
INNER JOIN table2 AS t2 ON t1.object_id = t2.id'
LEFT JOIN table3 AS t3 ON t2.category_id = t3.id
LEFT JOIN table4 AS t4 ON t2.section_id = t4.id
WHERE t1.object_group = 'com_group
ORDER BY t1.id DESC LIMIT 3;


---------- Добавлено 23.09.2017 в 12:53 ----------

LEOnidUKG, Но это никак не объясняет разницы в быстродействии
Synergy-Web:
А если не обновляться - страдает безопасность.

А ну-ка?

Договаривайте.. Какая безопасность?

Synergy-Web:
Опенкарт, ВП, Джумлу ломают гораздо чаще.

Опенкарт ломают из-за admin/admin Так можно сломать все что угодно. А еще его ломают через соседей.. Как и все другие..

Я так понимаю, что вы в большом курсе безопасности OC. Расскажите.

Всего: 2548