Этот запрос занимает много времени для загрузки в 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), чтобы этот запрос выполнялся быстрее?
Ждем ваших размышлений
Это сложный вопрос для ответа, поскольку существует множество переменных (вы упоминаете 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);
Я был бы удивлен, если индексирование будет проблемой, но стоит выстрел...
Для этого запроса:
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)
.
status
илиuserid
? Есть ли уtblinvoiceitems
индекс поinvoiceid
?*
вnot exists
(он получит все столбцы, в то время как вы проверяете только существование, вы можете простоselect null
здесьselect null
).