Оптимизация SQL-запросов (повсеместно)

У меня есть приложение PHP, которое извлекает информацию о заказе на основе отсканированного/введенного номера заказа для целей получения заказа. Мы используем Pervasive SQL, но синтаксис идентичен MS SQL.

У меня есть несколько небольших запросов, используемых для разбиения элементов комплекта на составные элементы, которые вызываются по мере необходимости, но они просты и быстры в выполнении. Моя проблема заключается в том, что наш основной запрос содержит самую необходимую информацию. Это быстро для большинства заказов, так как они относительно небольшие (1-15 предметов или около того). Моя проблема связана с большими заказами (например, оптом), которые могут составлять более 100 товаров.

Я понимаю, что чем больше информации требуется, тем больше времени потребуется для выполнения запроса, но я надеюсь, что в моем запросе есть место для его дальнейшей оптимизации.

Кто-нибудь видит в следующем запросе что-нибудь, что я могу оптимизировать, чтобы ускорить работу с большими заказами?

SELECT 
    oeordh.orduniq, 
    oeordh.customer, 
    oeordh.ordnumber, 
    oeordh.orddate, 
    oeordh.salesper1, 
    oeordd.orduniq, 
    oeordd.item, 
    oeordd.pickseq, 
    oeordd.location, 
    oeordd.origqty, 
    arcus.idcust, 
    arcus.idgrp 

FROM oeordh 
    INNER JOIN oeordd ON oeordh.orduniq = oeordd.orduniq
    INNER JOIN arcus ON oeordh.customer = arcus.idcust

WHERE 
    oeordh.ordnumber = '".$_POST['barcode']."' 

ORDER BY oeordd.pickseq`

person Donavon Yelton    schedule 29.02.2012    source источник
comment
Что вам говорит план запроса (через explain)?   -  person    schedule 29.02.2012
comment
Убедитесь, что у вас есть индексы для всех столбцов соединения, oeordh.ordnumber и oeordd.pickseq. Остальное зависит от мощности вашей базы данных/сервера.   -  person MicSim    schedule 29.02.2012
comment
две точки: 1. похоже на инъекцию; пожалуйста, начните использовать подготовленные операторы. 2. ваше соглашение об именах ужасно   -  person tereško    schedule 29.02.2012
comment
@tereško Я рассмотрю возможность использования подготовленных заявлений, спасибо за это! Кроме того, я не могу контролировать соглашение об именах, поскольку оно было выбрано программным обеспечением ERP.   -  person Donavon Yelton    schedule 01.03.2012


Ответы (2)


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

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

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

Редактировать: я действительно кое-что подумал, если эти поля не varchar, вы должны rtrim() их на стороне сервера вместо отправки тысяч и тысяч (или более) пробелов в конце каждого столбца.

person Blindy    schedule 29.02.2012
comment
Я думал, что такие вещи, как rtrim в запросе, замедляют запрос? Я также предполагаю, что вы имеете в виду бит $_POST в моем запросе... Теперь я назначил его как переменную до выполнения запроса. - person Donavon Yelton; 01.03.2012
comment
Зачем им замедлять запрос, вы (надеюсь) все равно обрезаете строку, зачем без необходимости переносить все эти пробелы по сети? И присвоение вещи переменной ничего не решит. - person Blindy; 01.03.2012
comment
Как еще мне позаботиться об инъекции? Я запрашиваю на основе значения, переданного через HTML-форму... - person Donavon Yelton; 01.03.2012
comment
Используйте параметры SQL или хотя бы передайте их через mysql_real_escape_string. - person Blindy; 02.03.2012

Вы, вероятно, не можете стать лучше, чем это. Мой профессор на курсе по базам данных однажды сказал: «Не пытайтесь умничать. RDMS хороша в оптимизации», за исключением одного: RDMS не устанавливает индексы автоматически. Итак, убедитесь, что у вас есть индексы для тех полей, по которым вы сортируете, объединяете и выбираете (выбираете, как в предложении «где»).

person Zyberzero    schedule 29.02.2012