Почему хранимые процедуры, выполняющие объединение нескольких таблиц, содержащих около 50 тыс. Строк, требуют много времени для выполнения? - PullRequest
0 голосов
/ 22 апреля 2020

У меня около 50 000 записей во всех таблицах, к которым присоединяются. Более или менее.

Но загрузка занимает около 15-20 секунд.

Кроме того, каждый является первичным ключом и присоединяется к нему.

Select 
            distinct H.EQHeaderID,H.EQUNR 'Equipment No', str.TPLNR 'Functional Location', H.STTXT 'Description', H.EQTYP 'Category', 
            H.DATAB 'Valid From', H.DATBI 'Valid To',

            H.SHTXT 'Technical Object Description', H.GUID,

            g.EQART 'Object Type', g.HERST 'Manufacturer', g.TYPBZ 'Model No',  
            g.SERGE 'Manufacturer Serial No', g.HERLD 'Manufacturer Country', g.BAUJJ 'Construction Year', g.BAUMM 'Construction Month',
            g.ANSDT 'Acquisition Date', g.BEGRU 'Authorization Group', g.ERDAT 'Creation Date',
            g.HZEIN 'Manufacturer Drawing Number',  g.INBDT 'Start-up Date of the Technical Object',
            g.ANSWT 'Aquisition Value',

            loc.SWERK 'Maint Plant', loc.STORT 'Location', loc.BEBER 'Plant Section',
            loc.ABCKZ 'ABC Indicator', loc.EQFNR 'Sort Field', loc.MSGRP 'Maintenance Planning Plant',

            Org.BUKRS 'Company Code', Org.ANLNR 'Asset', Org.GSBER 'Business Area', Org.KOSTL 'Cost Center', Org.PROID 'WBS Element',
            Org.GEWRK 'Work Center', Org.INGRP 'Planner group', Org.IWERK 'Maintenance Planning Plant',
            Org.KOKRS 'Controlling Area', Org.RBNR 'Catalog profile',

            str.HEQNR 'Superior Equipment', str.POSNR 'Position', str.SUBMT 'Const Type', 
            str.HEQUI 'Superordinate Equipment', str.TIDNR 'Technical Identification Number',

            ser.MATNR 'Material', Ser.SERNR 'Serial No', ser.LBBSA 'Stock Type No', ser.B_CHARGE 'Batch No', ser.B_LAGER 'Storage Location',
            ser.CHARGE 'Master Batch No',

            warr.GWLEN 'Warranty Date',

            cls.CLASS, cls.KLTXT 'Class Description', cls.KLART 'Class Type',

            h.EntryDateTime 'ReceivingDateTime', 
            Case when h.Transferred = 1 then 'Yes' else 'No' end 'Imported',
            h.TransferredModuleName 'Module'


            from dbo.EQ_Header h 

            left Join dbo.EQ_General g
            ON h.EQHeaderID= g.HeaderID
            left Join dbo.EQ_Location loc
            ON loc.HeaderID= h.EQHeaderID
            left Join dbo.EQ_Organizations org
            ON org.HeaderID= h.EQHeaderID
            left Join dbo.EQ_Structure str
            ON str.HeaderID= h.EQHeaderID
            left Join dbo.Eq_Classification cls
            ON cls.HeaderID= h.EQHeaderID
            left Join dbo.EQ_Serial ser
            ON ser.HeaderID= h.EQHeaderID
            left Join dbo.EQ_Warranty warr
            ON warr.HeaderID= h.EQHeaderID

            where h.EQUNR= '1231231'
            and Cast(h.EntryDateTime as Date) BETWEEN '2014-10-11' AND '2020-04-22'
            --and ISNULL(h.Transferred,0)=0

Я удалил фрагментацию. Кроме того, создан индекс для EQHeaderID, но по-прежнему нет прогресса.

1 Ответ

0 голосов
/ 22 апреля 2020

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

Предложение DISTINCT означает, что ВСЕ строки должны быть прочитаны и проанализированы на наличие дубликатов. один за другим, столбец за столбцом, и там много столбцов. (Какие типы данных присутствуют? Любые varchar (max) или другие длинные строки?) Существуют возможные приемы, если вы можете уменьшить набор столбцов, который должен быть DISTINCT.

Какова мощность EQ_Header.EQUNR ? Сколько строк произведет «1231231»? (Является ли тип данных правильным? Например, если это столбцы nvarchar, SQL придется преобразовать значение, отличное от nvarchar, в nvarchar, после чего он может выбрать сканирование таблицы по всему EQ_Header.)

Cast(h.EntryDateTime as Date) BETWEEN '2014-10-11' AND '2020-04-22' не сделает вещи быстрее, если (а) у вас нет индекса на Cast(h.EntryDateTime as Date) и (б) очень мало данных за этот шестилетний период, что кажется маловероятным. Возможный более эффективный способ установить это может быть

and h.EntryDateTime >= '2014-10-11' and h.EntryDateTime < '2020-04-23'

, но, опять же, это, вероятно, не будет иметь значения.

Для каждой строки, возвращаемой из EQ_Header, сколько строк - от каждого стола - ожидаете ли вы возвращения? Обратите внимание, что, поскольку они все являются левыми внешними объединениями, SQL, по сути, придется проходить через них l oop для каждой строки, найденной в EQ_Header, - если громкость высокая, это может быть проблемой.

...