2013-06-13 2 views
1

У меня есть таблица отношений, как показано ниже:SQL - запрос работает очень медленно

Table Relations Via phpmyadmin

бегаю следующий запрос из PHP и побежал в двух больших проблем.
1) Максимальный предел памяти превысил
2) Максимальное время выполнения превысило

SELECT DISTINCT venues.name, locations.location, events.event, types.type, foods.food, beverages.beverage, event_options.event_option, styles.style, space_requirements.space_requirement, features.feature 

FROM (SELECT * FROM venues v LIMIT $offset,$limit) venues 

INNER JOIN locations ON venues.location_id = locations.location_id 

LEFT JOIN venue_events ON venues.venue_id = venue_events.venue_id 
LEFT JOIN events ON events.event_id = venue_events.event_id 

LEFT JOIN venue_types ON venues.venue_id = venue_types.venue_id 
LEFT JOIN types ON types.type_id = venue_types.type_id 

LEFT JOIN venue_foods ON venues.venue_id = venue_foods.venue_id 
LEFT JOIN foods ON foods.food_id = venue_foods.food_id 

LEFT JOIN venue_beverages ON venues.venue_id = venue_beverages.venue_id 
LEFT JOIN beverages ON beverages.beverage_id = venue_beverages.beverage_id 

LEFT JOIN venue_event_options ON venues.venue_id = venue_event_options.venue_id 
LEFT JOIN event_options ON event_options.event_option_id = venue_event_options.event_option_id 

LEFT JOIN venue_styles ON venues.venue_id = venue_styles.venue_id 
LEFT JOIN styles ON styles.style_id = venue_styles.style_id 

LEFT JOIN venue_space_requirements ON venues.venue_id = venue_space_requirements.venue_id 
LEFT JOIN space_requirements ON space_requirements.space_requirement_id = venue_space_requirements.space_requirement_id 

LEFT JOIN venue_features ON venues.venue_id = venue_features.venue_id 
LEFT JOIN features ON features.feature_id = venue_features.feature_id 


Я использую этот запрос, чтобы получить все аксессуары, связанные с каждым местом. Мне нужно реализовать разбиение на страницы в бэкэнд, поэтому я использую LIMIT $ offset, $ limit в Sub Query. Я не мог найти никакой другой идеи (запроса), чтобы получить тот же результат, который я сейчас получаю. В настоящее время я использую

ini_set('memory_limit', '-1');
ini_set('max_execution_time', 60);

PHP функции, чтобы игнорировать эти проблемы, но я думаю, что это не лучшая практика. Также я думаю о том условии, когда мне, возможно, придется достать все принадлежности 50+ мест, для которых max_execution_time = 60 может быть недостаточно.

Как я могу избавиться от этой проблемы? Пожалуйста, помогите мне.

Обновленный
Числа строк извлекаемый (события * тип * еда * напитки * event_options * стили * space_requirements * особенность) каждое место есть. Но количество полезных для меня строк - это не умножение, а сумма.


И вот результат я нашел после того, как работает мой запрос с ключевым словом EXPLAIN

Array 
(
    [0] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => 
      [type] => ALL 
      [possible_keys] => 
      [key] => 
      [key_len] => 
      [ref] => 
      [rows] => 11 
      [Extra] => Using temporary 
     ) 

    [1] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => venue_events 
      [type] => ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 4 
      [ref] => venues.venue_id 
      [rows] => 3 
      [Extra] => Using index 
     ) 

    [2] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => events 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => serofero_mvb.venue_events.event_id 
      [rows] => 1 
      [Extra] => 
     ) 

    [3] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => venue_types 
      [type] => ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 4 
      [ref] => venues.venue_id 
      [rows] => 7 
      [Extra] => Using index 
     ) 

    [4] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => types 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => serofero_mvb.venue_types.type_id 
      [rows] => 1 
      [Extra] => 
     ) 

    [5] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => venue_foods 
      [type] => ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 4 
      [ref] => venues.venue_id 
      [rows] => 3 
      [Extra] => Using index 
     ) 

    [6] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => foods 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => serofero_mvb.venue_foods.food_id 
      [rows] => 1 
      [Extra] => Using index 
     ) 

    [7] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => venue_beverages 
      [type] => ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 4 
      [ref] => venues.venue_id 
      [rows] => 3 
      [Extra] => Using index 
     ) 

    [8] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => beverages 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => serofero_mvb.venue_beverages.beverage_id 
      [rows] => 1 
      [Extra] => 
     ) 

    [9] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => venue_event_options 
      [type] => ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 4 
      [ref] => venues.venue_id 
      [rows] => 2 
      [Extra] => Using index 
     ) 

    [10] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => event_options 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => serofero_mvb.venue_event_options.event_option_id 
      [rows] => 1 
      [Extra] => 
     ) 

    [11] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => venue_styles 
      [type] => ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 4 
      [ref] => venues.venue_id 
      [rows] => 1 
      [Extra] => Using index 
     ) 

    [12] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => styles 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => serofero_mvb.venue_styles.style_id 
      [rows] => 1 
      [Extra] => 
     ) 

    [13] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => venue_space_requirements 
      [type] => ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 4 
      [ref] => venues.venue_id 
      [rows] => 3 
      [Extra] => Using index 
     ) 

    [14] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => space_requirements 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => serofero_mvb.venue_space_requirements.space_requirement_id 
      [rows] => 1 
      [Extra] => 
     ) 

    [15] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => locations 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => venues.location_id 
      [rows] => 1 
      [Extra] => 
     ) 

    [16] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => venue_features 
      [type] => ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 4 
      [ref] => venues.venue_id 
      [rows] => 7 
      [Extra] => Using index 
     ) 

    [17] => Array 
     (
      [id] => 1 
      [select_type] => PRIMARY 
      [table] => features 
      [type] => eq_ref 
      [possible_keys] => PRIMARY 
      [key] => PRIMARY 
      [key_len] => 1 
      [ref] => serofero_mvb.venue_features.feature_id 
      [rows] => 1 
      [Extra] => 
     ) 

    [18] => Array 
     (
      [id] => 2 
      [select_type] => DERIVED 
      [table] => venues 
      [type] => ALL 
      [possible_keys] => 
      [key] => 
      [key_len] => 
      [ref] => 
      [rows] => 11 
      [Extra] => 
     ) 

) 


Thankyou

+2

Возможно, вам не хватает индексов. Запустите запрос непосредственно с ключевым словом 'EXPLAIN'. Приведите результат здесь. – datasage

+0

Я никогда не использовал индексы, поэтому я не знал о его силе. И спасибо за представление ключевого слова 'EXPLAIN', я буду использовать Google. Большое спасибо. – Lekhnath

+0

Каждый раз, когда вы соединяете два столбца вместе, каждый столбец должен иметь одинаковый тип данных сопоставления, и оба столбца должны быть проиндексированы. Это позволит mysql сортировать и сопоставлять строки намного быстрее. – datasage

ответ

2

создания индексов для столбцов, выбранных.

+0

Хорошо спасибо. Должен ли я создавать индекс для всех таблиц, которые 'JOINED' в вышеуказанном запросе? – Lekhnath

+0

Я создал индекс во всех таблицах, но проблема все еще остается. – Lekhnath

0

Вам необходимо изменить свой запрос на следующее:

SELECT DISTINCT venues.`name`, locations.`location`, events.`event`, types.`type`, foods.`food`, beverages.`beverage`, event_options.`event_option`, styles.`style`, space_requirements.`space_requirement`, features.`feature` 

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

Причина, по которой вы получаете эту ошибку, состоит в том, что индексы отсутствуют, и таким образом индексы будут определяться надлежащим образом и будут легко отличаться от PHP.

+0

Извините, но я не мог понять, что вы имеете в виду. – Lekhnath

0

На основе вывода EXPLAIN кажется, что запрос уже использует PRIMARY KEY в качестве индекса. Почему бы вам не попробовать разбить запрос.

Сначала получите идентификаторы мест, которые вы хотите отобразить (с разбивкой на страницы).

SELECT id FROM venues v LIMIT $offset,$limit 

$venue_ids = implode(',', $results); 

Затем запустите этот запрос.

SELECT DISTINCT venues.name, locations.location, events.event, types.type, foods.food, beverages.beverage, event_options.event_option, styles.style, space_requirements.space_requirement, features.feature 

FROM venues 

INNER JOIN locations ON venues.location_id = locations.location_id 

LEFT JOIN venue_events ON venues.venue_id = venue_events.venue_id 
LEFT JOIN events ON events.event_id = venue_events.event_id 

LEFT JOIN venue_types ON venues.venue_id = venue_types.venue_id 
LEFT JOIN types ON types.type_id = venue_types.type_id 

LEFT JOIN venue_foods ON venues.venue_id = venue_foods.venue_id 
LEFT JOIN foods ON foods.food_id = venue_foods.food_id 

LEFT JOIN venue_beverages ON venues.venue_id = venue_beverages.venue_id 
LEFT JOIN beverages ON beverages.beverage_id = venue_beverages.beverage_id 

LEFT JOIN venue_event_options ON venues.venue_id = venue_event_options.venue_id 
LEFT JOIN event_options ON event_options.event_option_id = venue_event_options.event_option_id 

LEFT JOIN venue_styles ON venues.venue_id = venue_styles.venue_id 
LEFT JOIN styles ON styles.style_id = venue_styles.style_id 

LEFT JOIN venue_space_requirements ON venues.venue_id = venue_space_requirements.venue_id 
LEFT JOIN space_requirements ON space_requirements.space_requirement_id = venue_space_requirements.space_requirement_id 

LEFT JOIN venue_features ON venues.venue_id = venue_features.venue_id 
LEFT JOIN features ON features.feature_id = venue_features.feature_id 

WHERE venues.id IN ($venue_ids) 

Это должно по крайней мере избавиться от производной таблицы.

+0

Спасибо за ваш ответ, но все равно много времени. Максимальный предел памяти превышен, а также время выполнения. Можно использовать ob_start() и ob_flush() для этой ситуации. Это 1:13 утра (Непал), и я не могу спать из-за этого. Боюсь, есть 52575 строк. Это нормально? – Lekhnath

+0

Итак, у вас есть 10 мест для начала, потому что они правые? Как вы закончили с 50k строк? –

+0

Потому что каждое место может иметь несколько событий, типов так далее и т. Д. Mysql дает мне экспоненциальное значение из 5 (событий) * 25 (типов) * 15 (продукты), и я беспомощен. – Lekhnath