2014-10-24 2 views
0

У меня есть программа, которая извлекает данные из таблицы Visual FoxPro и сбрасывает их в набор данных с помощью VB.net. Моя строка подключения отлично работает, и запрос, который я использую, обычно работает с приличной скоростью. Тем не менее, я понял, что в моей таблице большое количество «плохих» данных. Итак, теперь я пытаюсь уточнить свой запрос для буферизации против «плохих» данных, но то, что я считал очень маленьким, дало огромные потери производительности, и я не совсем уверен, почему.SQL Select/From/Where Run Speed ​​

Мой первоначальный запрос:

'Pull desired columns for orders that have not "shipped" and were received in past 60 days. 
'To "ship", an order must qualify with both an updated ship date and Sales Order #. 
sqlSelect = "SELECT job_id,cust_id,total_sale,received,due,end_qty,job_descr,shipped,so " 
sqlFrom = "FROM job " 
sqlWhere = "WHERE fac = 'North Side' AND shipped < {12/30/1899} AND so = '' AND received >= DATE()-60;" 
sql = sqlSelect & sqlFrom & sqlWhere 

Это имеет время выполнения около 20 секунд; в то время как я бы предпочел, чтобы это было быстрее, это не проблема. В моем первоначальном тестировании (и случайной отладке) я заменил sqlWhere на sqlWhere = "WHERE job_id = 127350". Это выполняется довольно быстро.

Теперь задача блока: После того, как я заменил sqlWhere с

'Find jobs that haven't "shipped" OR were received within last 21 days. 
'Recently shipped items are desired in results. 
sqlWhere = "WHERE fac = 'North Side' AND ((shipped < {12/30/1899} AND so = '') OR received >= DATE()-21);" 

Моя производительность подскочила до примерно 3 мин 40 сек. Это время почти точно такое же, как время для запуска с sqlWhere = "WHERE received >= DATE();".

Я не модератор этих таблиц; Я просто отвлекаюсь от них, чтобы создать серию отчетов для наших пользователей. Лучше всего предположить, что полученное поле не индексируется, это является причиной моего снижения производительности. Но в то время как мой первый поиск возвращает около 100 записей, вытягивание заданий только с сегодняшнего дня возвращает около 5, и по-прежнему занимает около 11 раз.

Итак, мой вопрос состоит из трех частей: 1) Кто-нибудь сможет объяснить явление, которое я испытываю прямо сейчас? Я чувствую, что я немного на правильном пути, но мои знания SQL были ограничены косвенным использованием в других языках ... 2) Есть что-то, что мне не хватает, или какой-то лучший способ получить результаты, которые мне нужны ? Есть большой объем записей, которые не «отправлены», а просто потому, что пользователь вводит только дату отправления или s/o и не делает другого. Мне нужен способ просмотреть самые последние заказы (независимо от статуса «отправлено»), а затем просмотреть менее свежие заказы с «плохими» данными, поэтому я могу заставить пользователя привыкнуть к очистке данных. 3) Плохо ли SQL-практика чрезмерно сузить предложение WHERE? Если я проведу пятнадцать полевых сравнений, объединенных вместе с вложенными идентификаторами AND/OR, я трачу свое время, когда могу делать что-то гораздо более чистым?

Большое спасибо, B

ответ

0

Если вы ищете Неиндексированные записи в вашей WHERE строки, SQL двигатель должен делать сканирование таблицы, то есть - смотреть на каждую запись в таблице.

Разница между двумя запросами заключается в том, что OR вместо AND. Когда у вас есть неиндексированный столбец в И, механизм SQL может использовать индексы, чтобы сузить количество записей, на которые он должен смотреть, для неиндексированного столбца. Когда у вас есть OR, теперь он должен смотреть на каждую запись в таблице и сравнивать ее с этим столбцом.

Добавление индекса в столбце Received может, вероятно, устранить проблему с производительностью.

В общем, есть две вещи, которые вы не хотите иметь в своем предложении WHERE. 1. Основное условие для неиндексированного столбца 2. Использование расчета по столбцу. Например, делать WHERE Shipped-2 < date() часто хуже, чем делать Отправлено < Date() + 2, потому что первое обычно не позволяет использовать индекс.

Уточнение вашего запроса через несколько предложений WHERE, как правило, хорошо. Чем меньше записей вам нужно вернуть в приложение, тем лучше будет ваша производительность, но вам необходимо иметь соответствующую индексацию.