VB6 SQL 2005 База данных Вопрос Вопрос - PullRequest
0 голосов
/ 09 сентября 2009

У меня есть приложение VB, которое обращается к базе данных SQL. Я думаю, что он работает медленно, и я подумал, что, возможно, у меня не было правильной индексации таблиц. Мне было интересно, как вы будете создавать индексы? Вот ситуация.

Мой основной цикл -

Select * from Docrec 
Order by YearFiled,DocNumb

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

Select * from Names 
Where YearFiled = DocRec.YearFiled 
and Volume = DocRec.Volume and Page = DocRec.Page  
Order by SeqNumb


Select * from MapRec
Where FiledYear = DocRec.YearFiled 
and Volume = DocRec.Volume and Page = DocRec.Page 
Order by SeqNumb

Надеюсь, я понял.

Ответы [ 4 ]

3 голосов
/ 09 сентября 2009

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

Если вместо SELECT * вы не сделаете выбор, выберите только нужные вам столбцы - таким образом вы не извлекаете столько данных.

Если вы это сделаете, то из SQL Server Management Studio (или чего бы вы ни использовали для управления SQL Server) вам нужно будет посмотреть, что проиндексировано, а что нет. Столбцы, по которым вы склонны искать больше всего, будут вашими первыми кандидатами в индекс.

Приложение
Теперь, когда я посмотрел ваше изменение, это может помочь понять, почему вы выполняете запросы так, как вы делаете, и посмотреть, нет ли способа объединить их в один запрос. Без большего контекста я бы просто угадал более оптимальные запросы.

3 голосов
/ 09 сентября 2009

Попробуйте в одном запросе, используя INNER JOIN:

SELECT * FROM Doctec d
    INNER JOIN Names n ON d.YearField = n.YearField AND d.Volume = n.Volume AND d.Page = n.Page
    INNER JOIN MapRec m ON m.FiledYear = n.YearFiled AND m.Volume = n.Volumen and m.Page = n.Page
ORDER BY YearFiled, DocNumb

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

0 голосов
/ 09 сентября 2009

Вообще, циклический просмотр записей - плохая идея. Разве вы не можете выполнить запрос на основе множеств, который дает вам все необходимое за один проход?

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

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

0 голосов
/ 09 сентября 2009

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

select columnlist from maprec m inner join docrec d on (m.filedyear = d.yearfield and m.volume = d.volume and m.page=d.page)

и снова для второго стола ...

Вы также можете урезать свои запросы, чтобы они возвращали только необходимые столбцы, а не возвращали все, если это возможно. Это должно помочь производительности.

Чтобы создать индекс самостоятельно в SQL Server 2005, перейдите к дизайну таблицы и выберите элемент панели инструментов Управление индексами и ключами.

Вы можете использовать помощник по настройке ядра СУБД. Вы можете создать трассировку (используя SQL Server Profiler) ваших запросов, а затем советник сообщит вам и создаст индексы, необходимые для оптимизации ваших запросов.

ОБНОВЛЕНИЕ ПОСЛЕ ВАШЕГО ПЕРВОГО КОММЕНТАРИИ МНЕ:

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

Прошло много времени с тех пор, как я сделал наборы записей VB6, НО я вспоминаю возможность фильтровать набор записей после возвращения из БД. Таким образом, в этом случае вы можете сохранить цикл, но вместо того, чтобы вызывать SQL каждый раз в цикле, вы просто фильтруете результирующие данные набора записей на основе первой записи. Вы бы инициализировали / загрузили второй и третий запрос перед этим циклом для загрузки данных. Используя приведенный выше синтаксис, я загружу в каждую из этих таблиц соответствие родительской таблице (docrec).

При этом вы по-прежнему только трижды попадете в БД, но при этом сохраните цикл, необходимый для обхода родительской таблицы docrec, чтобы вы могли работать над ней И с дочерними таблицами, когда у вас есть совпадение.

Вот несколько ссылок по фильтрации наборов записей ado .... http://www.devguru.com/technologies/ado/QuickRef/recordset_filter.html http://msdn.microsoft.com/en-us/library/ee275540(BTS.10).aspx http://www.w3schools.com/ado/prop_rs_filter.asp

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

select * from docrec d
left join maprec m on (d.YearFiled= m.FiledYear and d.Volume = m.Volume and d.Page = m.Page)
left join names n on  (d.YearFiled = n.YearFiled and d.Volume = n.Volume and d.Page = n.Page)

это вернет все записи DocRec И добавит все значения maprec и имена, где оно соответствует ИЛИ NULL, если нет.

Если это соответствует вашим потребностям, он попадет в БД только один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...