Наиболее эффективный способ загрузки DataSet из подмножества нескольких соединенных таблиц - PullRequest
0 голосов
/ 06 декабря 2011

У меня большая система инвентаризации, и мне приходится переписывать часть ее ввода-вывода.В его основе таблица продуктов и набор связанных таблиц.Я должен быть в состоянии прочитать части этого максимально эффективно.Из C # я строю этот запрос:

select *                                    -- includes productid
into #tt
from products where productClass = 547      -- possibly more conditions
select * from #tt;
select * from productHistory where productid in (select productid from #tt);
select * from productSuppliers where productid in (select productid from #tt);
select * from productSafetyInfo where productid in (select productid from #tt);
select * from productMiscInfo where productid in (select productid from #tt);
drop table #tt;

Этот запрос дает мне именно те результаты, которые мне нужны: 5 наборов результатов, каждый из которых имеет ноль, одну или несколько записей (если первый возвращает ноль строк, остальные также, конечно).Затем программа берет эти наборы результатов и помещает их в соответствующий DataSet.(Который затем передается конструктору, ожидающему только эти записи.) Этот запрос (с различными условиями) запускается lot .

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

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

Ответы [ 4 ]

2 голосов
/ 17 ноября 2012

Убедитесь, что при JOIN таблицах вы присоединяетесь к индексам. В противном случае вы закончите сканирование таблиц по сравнению с просмотром индекса, и ваш код будет очень медленным, особенно при объединении больших таблиц.

Рекомендуется оптимизировать запросы SQL, чтобы избежать сканирования таблиц.

2 голосов
/ 07 декабря 2011

Если у вас есть индекс для products.productClass, это может повысить производительность.

    select * from products where productClass = 547   -- includes productid    
    select productHistory.* 
    from productHistory 
    join products 
      on products.productid = productHistory.productid 
      and products,productClass = 547;
    ...   

Если productID является кластеризованным индексом, то, вероятно, вы получите лучшую производительность с

    CREATE TABLE #Temp (productid INT PRIMARY KEY CLUSTERED);
    insert into #temp
    select productid  from products where productClass = 547 
    order by productid;
    go
    select productHistory.* 
    from productHistory 
    join #Temp 
      on #Temp.productid = productHistory.productid; 

Объединение в кластеризованном индексе, кажется, дает лучшую производительность. Подумайте об этом - SQL может соответствовать первому и знать, что он может забыть об остальных, а затем перейти ко второму, зная, что он может двигаться вперед (не возвращаться к вершине).
С помощью оператора where in (select ..) SQL не может использовать порядок. Чем больше таблиц вам нужно присоединить, тем больше причин для #temp, поскольку при заполнении #temp у вас уходит около 1/2 секунды. Если вы собираетесь использовать #temp, вы также можете сделать его временным.

1 голос
/ 07 декабря 2011

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

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

Наконец, если вы не можете объединить данные, я не думаю, что есть более эффективный способ сделать это.

0 голосов
/ 07 декабря 2011

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

Однако вместо того, чтобы «втиснуть результаты в соответствующий набор данных»так как вы используете пакетную команду для возврата нескольких наборов результатов, вы можете использовать SqlDataAdapter, чтобы выполнить эту часть за вас:

SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet results = new DataSet();
adapter.Fill(results);

После этого первый набор результатов будет в результатов.второе место в результатах. Таблицы [1] и т. д.

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