MySQL сумасшедшая справка кросс-таблицы!

0

У меня есть этот запрос, который мне нужно выполнить, когда мне нужно проанализировать информацию о полях, сопоставляющую ее с другим полем в другой таблице, а затем ополоснуть и повторить несколько таблиц, в итоге это приведет к возврату требуемых строк.

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

Вот запрос:

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM (
      SELECT CU_id, CU_ship_name1, CU_ship_name2, CU_email
      FROM customers 
      WHERE CU_solicit=1 
      AND CU_cdate >=".$startDate." 
      AND CU_cdate <=".$endDate."
     )AS t1
INNER JOIN orders AS t2 ON t1.CU_id = t2.O_cid 
INNER JOIN item AS t3 ON t2.O_ref = t3.I_oref 
INNER JOIN product AS t4 ON t3.I_pid = t4.P_id 
INNER JOIN (
            SELECT C_id FROM category WHERE C_store_type =1
           ) AS t5 ON t4.P_cat = t5.C_id

Таблицы "клиенты", "заказы", ​​ "элемент" обновляются каждый месяц десятками тысяч новых строк, а таблица "продукт" получает по меньшей мере сто новых строк каждый месяц.

Единственное, что я мог подумать, это создать новую таблицу, содержащую эту информацию (которая не является идеальным решением) и добавить индекс к этим таблицам. Я боюсь индекса, так как эти таблицы получают такое большое количество новых данных, но я готов попробовать его (всегда можно отменить его правильно?). Однако я не считаю, что индекс сам по себе исправит проблему.

UPDATE: теперь я использую этот запрос и получаю более быстрые результаты, индексирование всех строк WHERE и JOIN ON не помогло мне вообще... Я не могу понять, почему.

Удаление подзапросов:

оказал катастрофическое влияние на мою скорость запроса, а также с 3-4 секунд на запрос ниже до 151 с теми же параметрами.

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM customers AS t1 
WHERE t1.CU_solicit=1 
AND t1.CU_cdate>= 20100725000000
AND t1.CU_cdate<= 20100801000000
AND EXISTS(
    SELECT NULL FROM orders AS t2
    INNER JOIN item AS t3 ON t2.O_ref = t3.I_oref 
    INNER JOIN product AS t4 ON t3.I_pid = t4.P_id 
    INNER JOIN (
        SELECT C_id 
        FROM category 
        WHERE C_store_type = 2
    ) AS t5 ON t4.P_cat = t5.C_id
    WHERE t1.CU_id = t2.O_cid);

Nevermind, я поменял их на обычные соединения и никаких подзапросов, и теперь эта вещь быстро осветляется после всего. Вот запрос:

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM customers AS t1 
JOIN orders AS t2 ON t1.CU_id = t2.O_cid 
JOIN item AS t3 ON t2.O_ref = t3.I_oref 
JOIN product AS t4 ON t3.I_pid = t4.P_id 
JOIN category AS t5 ON t4.P_cat = t5.C_id 
WHERE t1.CU_solicit =1 
AND t1.CU_cdate >=20100425000000
AND t1.CU_cdate <=20100801000000
AND t5.C_store_type =2
Теги:
join
multiple-tables

2 ответа

2
Лучший ответ

Я бы попробовал две вещи:

1) Добавьте индексы столбцов, которые вы используете в предложениях ON и WHERE

2) Исключите подзапросы, переписав их как обычные условия JOIN и WHERE

Только после того, как вы это сделали, и обнаружили, что у вас все еще проблема, если вы рассматриваете другие варианты.

Это действительно выглядит довольно простой запрос, за исключением ненужных подзапросов. Вы бы не ожидали, что он будет медленным даже с миллионами строк, если у вас нет указателей, у вас слишком мало памяти для MySQL, или вы очень плохо настроили сервер MySQL для доступных ресурсов.

Десять тысяч новых строк в месяц - ничто. Вы вводите новую строку каждые несколько минут. Это даже не соображение при определении того, какие индексы определять. MySQL на дешевом сервере может обрабатывать сотни вложений в секунду.

1

Я бы индексировал столбцы в ваших критериях так же, как и в ваших заявлениях ON. Индексы будут немедленно решать вашу проблему с сбоем и, вероятно, значительно не ухудшать ваши действия по изменению. Десятки тысяч строк каждый месяц на самом деле не так много строк - если ваша БД не находится на слабой машине.

Кроме того, я бы посмотрел на полное удаление подзапросов. Они часто замедляют производительность сервера sql. Вы также можете просмотреть перемещение запроса в хранимую процедуру, чтобы у сервера была возможность кэшировать его план выполнения.

  • 0
    Спасибо, я проиндексировал столбцы ON и WHERE, но это не внесло заметных изменений, какие-либо другие предложения? Кроме того, удаление параметра заняло у меня от 6-9 секунд для моих тестовых параметров до 151 секунды ... так что все пошло совершенно по-другому, что касается подзапросов, так что теперь я в замешательстве, ха.
  • 0
    Хорошо, я понял, что могу узнать вас по работе, которую вы наняли для меня в Сан-Диего @ SMS. Если это вы, я надеюсь, у вас все хорошо, Таннер Смит.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню