Что не так с этим запросом MySQL? (Whmcs)

0

Этот запрос занимает много времени для загрузки в php-приложение. Фактически, он не загружается вообще.
Есть около 17 тыс. Записей tblinvoices.

SELECT * 
FROM 'tblinvoices' 
WHERE NOT EXISTS ( 
  SELECT * 
  FROM 'tblinvoiceitems' 
  WHERE 'tblinvoiceitems'.'invoiceid' = 'tblinvoices'.'id' 
    AND 'type' IN ( 'Invoice' ) 
) AND 'status' = 'Unpaid' 
  AND 'userid' = '19830'

Есть ли что-нибудь, что я могу сделать на стороне сервера (конфигурация Mysql), чтобы этот запрос выполнялся быстрее?

Ждем ваших размышлений

  • 0
    У вас есть индекс status или userid ? Есть ли у tblinvoiceitems индекс по invoiceid ?
  • 0
    Вы пробовали объяснить план, используя инструмент, такой как MySQL Workbench или sqldeveloper? Также вам следует избегать оператора * в not exists (он получит все столбцы, в то время как вы проверяете только существование, вы можете просто select null здесь select null ).
Показать ещё 4 комментария
Теги:
performance

2 ответа

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

Это сложный вопрос для ответа, поскольку существует множество переменных (вы упоминаете PHP), и мы не знаем, какой экземпляр сервера размера вы используете, не говоря уже о том, какие другие службы и т.д.

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

Первым шагом будет удаление PHP из уравнения. Просто попробуйте в MySQL CLI.

Вы пытались запустить тот же запрос в тестовой базе данных с гораздо меньшим набором данных?

Поскольку ваше приложение закодировано, очень сложно нормализовать вашу базу данных, но вы все равно можете запустить EXPLAIN в запросах и предоставить вам доступ к базе данных, которую вы можете добавить и удалить индексы по мере необходимости.

Попробуйте добавить следующие индексы...

CREATE INDEX idx_invoices_user_status ON tblinvoices(status,userid);

А также...

CREATE INDEX idx_invoiceitems_invoiceid_type ON tblinvoiceitems(invoiceid,type);

Я был бы удивлен, если индексирование будет проблемой, но стоит выстрел...

  • 0
    ОШИБКА 1170 (42000): столбец BLOB / TEXT 'status' используется в спецификации ключа без длины ключа Есть идеи? Я не знаю много о SQL
  • 0
    Возможно, вы захотите удалить статус из индекса или если вы можете изменить тип статуса, это действительно не должно быть BLOB. Используйте varchar с леном максимального лен статуса ...
Показать ещё 2 комментария
0

Для этого запроса:

SELECT i.* 
FROM tblinvoices i 
WHERE NOT EXISTS (SELECT 1
                  FROM tblinvoiceitems ii
                  WHERE ii.invoiceid = i.id AND ii.type = 'Invoice'
                 ) AND 
     i.status = 'Unpaid' AND
     i.userid = '19830';

Вы хотите индексы на tblinvoices(userid, status, id) и tblinvoiceitems(invoiceid, type).

Ещё вопросы

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