Оптимизировать результат SQL для ScreenWriter

0

У меня есть программа, которая читает в папке файлов (4 ГБ все вместе), индексирует их, а затем добавляет их в связанную базу данных SQL. Все это происходит еще до того, как форма загружается.

Теперь я хочу получить еще один файл, содержащий одно 13-значное число в каждой строке, и запросить в базе данных SQL из VB поиск каждого номера, чтобы узнать, какая папка, файл и номер строки содержат это число.

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

Dim result = From n In System.IO.File.ReadLines("G:\USER\SearchThese.txt")
                     Select n.Substring(0, 13)


Dim MyFilePath As String
Dim linePos As String
Dim lines As String
'-- connection
Dim con As New SqlConnection(***MY SQL CONNECTION***)

Dim dataset As New DataSet
Dim datatable As DataTable
Dim dataadapter As New SqlDataAdapter
Dim sql As String

Dim i As Integer

'-- command
Dim cmd As New SqlCommand()
con.Open()

Using sw As New StreamWriter("G:\USER\TESTRUN1.txt")
    For Each word As String In result
        i = 0
        sql = ("SELECT * FROM Test_Table WHERE DigNum = @word")
        dataadapter = New SqlDataAdapter(sql, con)
        dataadapter.SelectCommand.Parameters.AddWithValue("@word", word)
        dataset = New DataSet()
        dataadapter.Fill(dataset, "Test_Table")

        While i < dataset.Tables("Test_Table").Rows.Count

            linePos = dataset.Tables("Test_Table").Rows(i).Item(4).ToString()
            MyFilePath = dataset.Tables("Test_Table").Rows(i).Item(1).ToString()
            i += 1
            Using sr As New StreamReader(MyFilePath)
                For n As Integer = 1 To linePos
                    lines = sr.ReadLine
                Next
                sw.WriteLine(lines)
            End Using

        End While


   Next

End Using
MsgBox("Complete!") 

Как я уже сказал, это прекрасно работает, но даже поиск только 5 номеров занимает довольно много времени. Я предполагаю, что потоковая программа замедляет его, но я не знаю.

Для всех, кто спрашивает, моя таблица базы данных имеет следующие столбцы:

DigNum | FilPth | FilDte | DteAdd | LnePos
  • 0
    Если содержимое файла не изменяется (за исключением случаев добавления), вам следует рассмотреть возможность сохранения позиции внутри файлов. Гораздо проще сказать «прочитать строку, начинающуюся с позиции 23423», а не «прочитать 423-ю строку»
  • 0
    Извините @the_lotus не думаю, что я полностью понимаю
Показать ещё 5 комментариев
Теги:
seek

2 ответа

0

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

Using sw As New StreamWriter("G:\USER\TESTRUN1.txt")
            For Each word As String In result
                i = 0
                sql = "SELECT * FROM Test_Table WHERE DigNbr = @word"
                dataadapter = New SqlDataAdapter(sql, con)
                dataadapter.SelectCommand.Parameters.AddWithValue("@word", word)
                dataset = New DataSet()
                dataadapter.Fill(dataset, "Test_Table")

                While i < dataset.Tables("Test_Table").Rows.Count

                    linePos = dataset.Tables("Test_Table").Rows(i).Item(4).ToString()
                    MyFilePath = dataset.Tables("Test_Table").Rows(i).Item(1).ToString()
                    i += 1


                    Using sr As New StreamReader(MyFilePath)
                        sr.BaseStream.Seek(4096 * (linePos - 1), SeekOrigin.Begin)
                        FoundWords.Add(sr.ReadLine)
                        For Each item As String In FoundWords
                            sw.WriteLine(item)

                        Next
                        FoundWords.Clear()
                    End Using

В основном, для любого, кто читал, я использовал метод поиска, каждая строка - 4096 байт, другими словами, новая строка начинается каждые 4097, так что с моим номером строки, который у меня есть, который указывает, на какой строке находится 13-значный номер, который я ищу, я просто умножьте его так, чтобы поиск шел прямо к этому байту (строке) и получал строку.

например, скажите, что я был в строке 10, 4096 * 10 - это 40960, где начинается строка 10. Как и в комментариях, вместо поиска строки 55 я в основном ищу позицию (55 * 4096).

Я плохо объясняю, но надеюсь, что это кому-то поможет.

0

Когда вы пытаетесь оптимизировать производительность в таком фрагменте кода, вам нужно измерять производительность на основе вызовов. Это можно сделать с помощью инструментов профилирования Visual Studio (см. Https://docs.microsoft.com/en-us/visualstudio/profiling/profiling-feature-tour?view=vs-2017).

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню