/ / Przyspieszenie kwerendy SQL korzystającej z FullText Join - mysql, database, performance, join, left-join

Przyspieszenie kwerendy SQL, która używa połączenia FullText - mysql, baza danych, wydajność, join, lewostronne

Mam sytuację, w której muszę JOIN i wewnętrzne zapytanie z bazy danych produktów, grupowanie elementów według nazwy, a następnie użycie kolumny nazwy do wykonania łączenia, a więc:

SELECT p.*, p3.variants, sl.id, l.name as locationName FROM products p
LEFT JOIN (SELECT item, count(DISTINCT id) as variants FROM products GROUP BY item) p3
ON p3.item = p.item
LEFT JOIN stockLevels sl ON sl.id=p.id
LEFT JOIN locations l ON l.id=sl.stockLocation AND l.showStock="1"
WHERE p.id="10459" GROUP BY p.id

Po pomieszaniu z kolejnością JOIN a samo zapytanie określiło, że utworzenie pierwszej tabeli wewnętrznej i wykonanie pierwszego wymaganego sprzężenia zmienia prędkość zapytania, ale sprzężenie wewnętrzne (SELECT item, count(DISTINCT id) as variants FROM products GROUP BY item) daje (obecnie) 7034 wiersze, co jest niepotrzebne, ponieważ wymagane jest tylko około 5.

Jeśli zmodyfikuję wewnętrzne sprzężenie do:

(SELECT item, count(DISTINCT id) as variants
FROM products *WHERE item LIKE "%SOME VALUE%"* GROUP BY item)

To oczywiście zmniejsza liczbę wierszy zwróconych przez to sprzężenie wewnętrzne i jest około dwa razy szybsze.

Ale nie mogę tego zrobić, ponieważ nie mam żadnej znanej wartości, którą można użyć do wewnętrznego where klauzula.

Czy jest jakikolwiek sposób, że mogę doprowadzić wyniki z zewnętrznego stołu do wnętrza i utworzyć wewnętrzne zapytanie, które odwołuje się do zewnętrznego, tj .:

SELECT p.*, p3.variants, sl.id, l.name as locationName FROM products p
LEFT JOIN (SELECT item, count(DISTINCT id) as variants
FROM products *WHERE item LIKE p.item * GROUP BY item) p3  << New Where Clause
ON p3.item = p.item
LEFT JOIN stockLevels sl ON sl.id=p.id
LEFT JOIN locations l ON l.id=sl.stockLocation AND l.showStock="1"
WHERE p.id="10459" GROUP BY p.id

Wiem, że to, co napisałem powyżej, nie zadziałało i nie rozumiałem dlaczego, ale czy istnieje sposób, w jaki mogę coś osiągnąć na tych liniach?

Biorąc pod uwagę liczbę rekordów w mojej bazie danych, nie stanowi to problemu, dane są przesyłane bardzo szybko, ale mogę sobie wyobrazić, że z czasem, kiedy dane się rozrosną, może tak być.

Zauważ, że patrzyłem na robienie parentId kolumna całkowita, zamiast grupowania według pełnego tekstu item ale w mojej aplikacji jest wiele innych problemów, ale i tak nie przyspieszyło to zapytania, z tych samych powodów, które wymieniono powyżej, wewnętrzne wciąż musiały zwracać wszystkie wiersze

Zwróć też uwagę, to jest MySQL

Jeśli to w ogóle pomaga, oto wynik z EXPLAIN

wprowadź opis obrazu tutaj

Odpowiedzi:

0 dla odpowiedzi № 1

Jeśli potrzebujesz tylko 5, zrób to w klasyczny sposób:

SELECT
p.*,
p3.variants,
sl.id,
l.name as locationName,
(SELECT count(DISTINCT id)
FROM products
WHERE item LIKE p.item GROUP BY item) total
FROM products p
LEFT JOIN stockLevels sl
ON sl.id=p.id
LEFT JOIN locations l
ON l.id=sl.stockLocation AND l.showStock="1"
WHERE p.id="10459" GROUP BY p.id

Tutaj możesz uzyskać dostęp do tabeli nadrzędnej.


2 dla odpowiedzi nr 2

Możesz umieścić skorelowane podkwerendy w SELECT klauzula:

SELECT p.*, sl.id, l.name as locationName,
(SELECT COUNT(distinct id)
FROM products p3
WHERE p3.item = p.item) as variants
FROM products p
LEFT JOIN stockLevels sl ON sl.id=p.id
LEFT JOIN locations l ON l.id=sl.stockLocation AND l.showStock="1"
WHERE p.id="10459" GROUP BY p.id