Петля работает очень медленно - PullRequest
1 голос
/ 20 апреля 2011

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

вот что мне нужно: 1. загрузить gridview из загруженного файла Excel (это будетвероятно, будет около 300 записей или около того) 2. сравните производителя, модель и серийный номер с моей базой данных MS SQL (около 20 000 записей), чтобы выяснить, есть ли совпадение.

'find source ID based on make/model/serial No combination.
        Dim cSource As New clsSource()
        Dim ds As DataSet = cSource.GetSources()
        Dim found As Boolean = False

        'populate db datatables
        Dim dt As DataTable = ds.Tables(0)
        Dim rows As Integer = gwResults.Rows.Count()
        For Each row As GridViewRow In gwResults.Rows
            'move through rows and check data in each row against the dataset
            '1 - make
            For Each dataRow As DataRow In dt.Rows
                found = False
                If dataRow("manufacturerName") = row.Cells(1).Text Then
                    If dataRow("modelName") = row.Cells(2).Text Then
                        If dataRow("serialNo") = row.Cells(3).Text Then
                            found = True
                        End If
                    End If
                End If

                'display results
                If found Then
                    lblResults.Text += row.Cells(1).Text & "/" & row.Cells(2).Text & "/" & row.Cells(3).Text & " found"
                Else
                    lblResults.Text += row.Cells(1).Text & "/" & row.Cells(2).Text & "/" & row.Cells(3).Text & " not found "
                End If

            Next
        Next

, есть ли лучший способнайти совпадение между двумя?я умираю здесь.

Ответы [ 3 ]

2 голосов
/ 20 апреля 2011

Для каждой из ваших 300 строк сетки вы просматриваете все 20 тыс. Датаров. Это составляет 300 * 20k = 6 миллионов итераций цикла. Не удивительно, что ваша петля медленная. : -)

Позвольте мне предложить следующий алгоритм (псевдокод):

For Each gridviewrow
    Execute a SELECT statement on your DB with a WHERE clause that compares all three components
    If the SELECT statement returns a row
        --> found
    Else
        --> not found
    End If
Next

С этим решением у вас есть только 300 итераций цикла. В каждой итерации цикла вы делаете SELECT для базы данных. Если вы правильно проиндексировали свою базу данных (т. Е. Если у вас есть составной индекс для полей manufacturerName, modelName и serialNo), то этот SELECT должен быть очень быстрым - намного быстрее, чем циклически проходить по всем 20 тысячам датаров.

С математической точки зрения это сократит временную сложность вашего алгоритма с O(n * m) до O(n * log m), при этом n обозначает количество строк в вашем сеточном представлении и m количество записей в вашем базы данных.

1 голос
/ 20 апреля 2011

Пока ответ Хайнци верен; может быть более выгодно выполнить дорогой запрос SQL перед циклом и фильтровать, используя представления данных, чтобы вы не обращались к БД 300 раз

Execute a SELECT statement on your DB 
For Each gridviewrow
    if my datagridview.Select(String.format("manufacturerName={0}", row.item("ManufacturerName"))
    If the dataview has a row
        --> found
    Else
        --> not found
    End If
Next

ПРИМЕЧАНИЕ: я сравнил только один критерий, чтобы проиллюстрировать эту точку, вы можете отфильтровать все три здесь

0 голосов
/ 20 апреля 2011

Хм ... как насчет загрузки данных из электронной таблицы в таблицу в базе данных tempdb, а затем записи выбора, который сравнивает строки так, как вы хотите их сравнить? Таким образом, все сравнения данных выполняются на стороне сервера, и вы сможете использовать все возможности своего экземпляра SQL.

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