Что нового

Как правильно и быстро считывать данные из SQL базы?

MrSokol

Новичок
Сообщения
11
Репутация
0
Приветствую!
Подскажите, пожалуйста, начал потихоньку смотреть SQL в AutoIt'е и возник вопрос как быстро считать данные из базы?
Для примера набросал такой скрипт:
Код:
#include <SQLite.au3>
Local $hQuery, $aRow

_SQLite_Startup()
_SQLite_Open('test.db')
_SQLite_Exec(-1, "CREATE TABLE Test (some);")
$sql = "BEGIN;"
For $i = 1 To 100000
   $sql &= "INSERT INTO Test (some) VALUES ('"&$i&"');"
Next
$sql &= "COMMIT;"
_SQLite_Exec(-1, $sql)
$k = 0
$hTim = TimerInit()
_SQLite_Query(-1, "SELECT * FROM Test", $hQuery)
While _SQLite_FetchData($hQuery, $aRow) = $SQLITE_OK
   ; тут код, для примера пусть будет счетчик
   $k += 1
WEnd
ConsoleWrite('Time = ' & TimerDiff($hTim) / 1000 & @CRLF)
ConsoleWrite('K = ' & $k & @CRLF)

Код:
Time = 9.24589478185422
K = 100000
так вот, получилось 9 секунд для считывания и фетча данных, что помоему достачно много. Как более правильно считывать данные?
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Код:
#include <SQLite.au3>
Local $hQuery, $aRow,$aResult, $iRows, $iColumns

_SQLite_Startup()
_SQLite_Open('test.db')
_SQLite_Exec(-1, "CREATE TABLE Test (some);")
$sql = "BEGIN;"
For $i = 1 To 100000
   $sql &= "INSERT INTO Test (some) VALUES ('"&$i&"');"
Next
$sql &= "COMMIT;"
_SQLite_Exec(-1, $sql)
$k = 0
$hTim = TimerInit()
;~ _SQLite_Query(-1, "SELECT * FROM Test", $hQuery)
;~ While _SQLite_FetchData($hQuery, $aRow) = $SQLITE_OK
;~    $k += 1
;~ WEnd
_SQLite_GetTable2d(-1, "SELECT * FROM Test", $hQuery,$aResult, $iRows, $iColumns)
ConsoleWrite('Time = ' & TimerDiff($hTim) / 1000 & @CRLF)
ConsoleWrite('K = ' & $k & @CRLF)

Примерно в 2 раза быстрее.
 
Автор
M

MrSokol

Новичок
Сообщения
11
Репутация
0
sngr сказал(а):
Примерно в 2 раза быстрее.
что-то у меня наоборот медленнее:
Код:
Time = 10.2774271672133
K = 0
ADD:
нашел ошибку, тут:
Код:
_SQLite_GetTable2d(-1, "SELECT * FROM Test", $hQuery,$aResult, $iRows, $iColumns)

$hQuery лишний
Код:
_SQLite_GetTable2d(-1, "SELECT * FROM Test", $aResult, $iRows, $iColumns)

но все равно:
Код:
Time = 9.82929270876701
K = 0
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
На самом деле SQLite обрабатывает этот запрос очень быстро:
Код:
#include <SQLite.au3>
Local $hQuery, $aRow, $aResult, $iRows, $iColumns
_SQLite_Startup()
_SQLite_Open('test.db')
_SQLite_Exec(-1, "CREATE TABLE Test (some);")
$sql = "BEGIN;"
For $i = 1 To 100000
   $sql &= "INSERT INTO Test (some) VALUES ('"&$i&"');"
Next
$sql &= "COMMIT;"
_SQLite_Exec(-1, $sql)
$hTim = TimerInit()
_SQLite_Query(-1, "SELECT * FROM Test;", $hQuery)
ConsoleWrite('Time = ' & TimerDiff($hTim) / 1000 & @CRLF)
_SQLite_Exec(-1, "DROP TABLE Test;")

Код:
Time = 0.000306290206603168
Дольше происходит конвертация полученных данных в массив AutoIt.
А теперь про запросы - это ненормально получать за один раз 100000 строк - на практике это редко применимо (ладно если вы эти данные дальше будете обрабатывать в памяти, а вот если их понадобиться вывести в GUI, то процесс затянется на долго), лучше будет вводить условия для выборки данных (WHERE) или пользоваться "постраничным" выводом (LIMIT & OFFSET).

Пример для LIMIT:
Код:
#include <SQLite.au3>
#include <Array.au3>
Local $hQuery, $aRow, $aResult, $iRows, $iColumns
_SQLite_Startup()
_SQLite_Open('test.db')
_SQLite_Exec(-1, "CREATE TABLE Test (some);")
$sql = "BEGIN;"
For $i = 1 To 100000
   $sql &= "INSERT INTO Test (some) VALUES ('"&$i&"');"
Next
$sql &= "COMMIT;"
_SQLite_Exec(-1, $sql)
$hTim = TimerInit()
_SQLite_GetTable2d(-1, "SELECT * FROM Test LIMIT 100 OFFSET 90000;", $aResult, $iRows, $iColumns)
ConsoleWrite('Time = ' & TimerDiff($hTim) / 1000 & @CRLF)
_SQLite_Exec(-1, "DROP TABLE Test;")
_ArrayDisplay($aResult)

LIMIT ограничивает выборку количеством строк, а OFFSET задает строку с которой ее производить.
 
Автор
M

MrSokol

Новичок
Сообщения
11
Репутация
0
Redline,
Большое спасибо за развернутое обьяснение, пойду смотреть синтаксис SQLite :smile:
 
Верх