Zaloguj się by uzyskać pełen dostęp. Nie masz jeszcze konta? Założ je już teraz w kilka sekund.

Wysłany: 2014-07-04, 23:17


shiny







Wiek: 35
Na forum: 6130 dni
Posty: 14

Piwa: 17

Respekt: 63

Helo?. Od niedawna bawi? si? w MTA j?zykami bazodanowymi (czyli wbudowanymi SQLite i MySQL). Niby nauczy?em si? ju? wykonywa? podstawowe zapytania, ale jak widz?, SQLite jest ponad 10 razy wolniejsze przy wykonywaniu SELECT. Zastosowa?em transakcje, kt?re powinny by? wsz?dzie dla tego j?zyka (zastosowa?em si? do tego poradnika), wykonuj? zapytania 250,000 razy (!) i z tego co zauwa?y?em:
- INSERT w SQLite dzia?a o kilkana?cie, czasem kilkaset milisekund szybciej (!)
- SELECT w SQLite dzia?a o ponad 10 razy wolniej

Dla test?w w??czy?em te? transakcje dla obu j?zyk?w (tak mi poleci? Tey) i w?a?nie od tego czasu zauwa?y?em, ?e SQLite si? "krztusi". Czy da si? to jako? zoptymalizowa??

Dodam te? tekst z log?w, coby udowodni?, ?e rzeczywi?cie SQLite ma problem z wykonywaniem SELECT:
Kod:

[10] INFO: Czas wykonania p?tli - 3917 milisekund.
[10] INFO: Po??czono z baz? danych.
[10] INFO: Pomy?lnie wype?niono tabel? w SQLite. Czas trwania to 3548 milisekund
[10] INFO: Pomy?lnie wype?niono tabel? w MySQL. Czas trwania to 3640 milisekund
[10] INFO: Pomy?lnie wybrano z tabeli. Czas trwania dla SQLite to 1678 milisekund
[10] INFO: Pomy?lnie wybrano z tabeli. Czas trwania dla MySQL to 182 milisekund

A tutaj kod:
local MySQL_HOST  "HOST"
local MySQL_USER  "USER"
local MySQL_PASS  "PASS"
local MySQL_DB    "DB"
local MySQL_PORT  3306

local Connection        dbConnect("sqlite""sqlite.db")
local MySQLConnection   dbConnect("mysql""dbname=" .. MySQL_DB .. ";host=" .. MySQL_HOSTMySQL_USERMySQL_PASS"share=1""port=" .. MySQL_PORT)
local TABELA            "TABELA"
local Handler_DB        nil
local Number            250000

addEventHandler("onResourceStart"resourceRoot, function()
    HandleQuery dbQuery(Connection"CREATE TABLE IF NOT EXISTS " .. TABELA .. " (Tekst TEXT, ID INTEGER);")
    MySQLQuery dbQuery(MySQLConnection"CREATE TABLE IF NOT EXISTS " .. TABELA .. " (Tekst TEXT, ID INT(2);")
    local Result dbPoll(HandleQuery, -1) and dbFree(HandleQuery) and dbPoll(MySQLQuery, -1) and dbFree(MySQLQuery)
    
    local NOW getTickCount()
    
    for 0Number do
        print()
    end
    local TIME__ getTickCount() - NOW
    outputDebugString("Czas wykonania p?tli - " .. TIME__ .. " milisekund."3)
    
    if not Connection then
        outputDebugString("Brak po??czenia z baz? danych SQLite."1)
    elseif not MySQLConnection then
        outputDebugString("Brak po??czenia z baz? danych MySQL."1)
    else
        outputDebugString("Po??czono z baz? danych."3)
        Fill_Table()
        Show_Table()
    end
end)

function Fill_Table()
    local NOW getTickCount()
    SQLite_Query dbQuery(Connection"BEGIN TRANSACTION;")
    for 0Number do
        SQLite_Query dbQuery(Connection"INSERT OR REPLACE INTO " .. TABELA .. " (Tekst, ID) VALUES (?, ?)""Tekst nr" .. ii)
    end
    SQLite_Query dbQuery(Connection"END TRANSACTION;")
    local Difference getTickCount() - NOW
    outputDebugString("Pomy?lnie wype?niono tabel? w SQLite. Czas trwania to " .. Difference .. " milisekund"3)

    local NOW__ getTickCount()
    MySQL_Query dbQuery(MySQLConnection"START TRANSACTION;")
    for i__ 0Number do
        MySQL_Query dbQuery(Connection"INSERT INTO " .. TABELA .. " (Tekst, ID) VALUES (?, ?)""Tekst nr" .. i__i__)
    end
    MySQL_Query dbQuery(MySQLConnection"COMMIT;")
    local Difference__ getTickCount() - NOW__
    outputDebugString("Pomy?lnie wype?niono tabel? w MySQL. Czas trwania to " .. Difference__ .. " milisekund"3)
end

function Show_Table()
    local NOW getTickCount()
    local QUERY__ dbQuery(Connection"BEGIN TRANSACTION;")
    local QUERY__ dbQuery(Connection"SELECT ID FROM " .. TABELA .. "")
    local QUERY__ dbQuery(Connection"END TRANSACTION;")
    local Result dbPoll(QUERY__, -1) and dbFree(QUERY__)
    local Difference getTickCount() - NOW
    outputDebugString("Pomy?lnie wybrano z tabeli. Czas trwania dla SQLite to " .. Difference .. " milisekund"3)
    
    local NOW__ getTickCount()
    local QUERY____ dbQuery(MySQLConnection"START TRANSACTION")
    local QUERY____ dbQuery(MySQLConnection"SELECT ID FROM " .. TABELA)
    local QUERY____ dbQuery(MySQLConnection"COMMIT;")
    local Result dbPoll(QUERY____, -1) and dbFree(QUERY____)
    local Difference__ getTickCount() - NOW__
    outputDebugString("Pomy?lnie wybrano z tabeli. Czas trwania dla MySQL to " .. Difference__ .. " milisekund"3)
end

addCommandHandler("insert"Fill_Table)
addCommandHandler("show"Show_Table)

I teraz podstawowe pytanie - czy ja robi? co? ?le, czy mo?e ?le u?ywam SQLite, czy po prostu samo SQLite nie daje sobie rady z tak? liczb? zapyta??

Ostatnio zmieniony przez shiny 2014-07-05, 12:56, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 

 
Wysłany: 2014-07-05, 17:45


Riot

3X






Wiek: 29
Na forum: 5729 dni
Posty: 1123
Nick w MP: Riot/3X

Piwa: 286

Respekt: 123
Respekt: 123

Nada?e? indeksy na kolumny kt?re przeszukujesz? ;)

Postaw piwo autorowi tego posta
 

 
Wysłany: 2014-07-05, 19:27


Wielebny







Wiek: 41
Na forum: 5498 dni
Posty: 257
Nick w MP: Wielebny

Piwa: 1690

Respekt: 180
Respekt: 180Respekt: 180

"Riot" napisał/a:

Nada?e? indeksy na kolumny kt?re przeszukujesz? ;)


Nie nada?, ale to powinno by? bez znaczenia - i tak pobiera wszystkie dane z tych tabel. Ale faktycznie w?tkotw?rca nie powinien tworzy? tabel bez indeks?w.

Sprawa jest te? taka, ?e podany kod nie korzysta z bazy danych, tak jakby to by?a baza danych, tylko jak plik tekstowy - ot wrzuca tam dane a p??niej wszystkie pobiera. Jesli faktycznie chcemy porownac te dwie bazy to nale?a?oby faktycznie skorzysta? z kluczy i select?w operuj?cych na podzbiorach danych.

Trzeba miec te? na uwadze, ?e SQLite jest po prostu plikiem na dysku, a po??czenie MySQL mo?e by? ze zdalnym hostem - nie wiem co tam wpisa?e? w MYSQL_HOST, ale je?li to nie jest host lokalny to do komunikacji z MySQL dochodzi te? latencja sieciowa. Opr?cz tego, nawet z serwerem lokalnym mo?na po??czy? si? przez socket TCP i socket UNIXowy. Ten drugi jest szybszy.

Inna sprawa jest taka, ?e odradzam korzystanie zar?wno z transakcji jak i tabel InnoDB. Napisa?em wiele gamemod?w i naprawd? nie mia?em jeszcze potrzeby zachowania atomiczno?ci serii operacji w bazie danych a do typowych operacji tabele MyISAM s? po prostu szybsze.

Postaw piwo autorowi tego posta
 

 
Więcej szczegółów
Wystawiono 1 piw(a):
shiny
Tagi: przyspieszenie :: quotselectquot :: sqlite :: się :: szybciej?
Anonymous





Na forum: 245 dni
Posty: 1



Anonymous Koniecznie zajrzyj na:






Skocz do:  
Wyświetl posty z ostatnich:   
GTAONLINE.PL » JĘZYKI PROGRAMOWANIA » LUA Ten temat jest zablokowany bez możliwości zmiany postów lub pisania odpowiedzi

Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Dodaj temat do Ulubionych
Wersja do druku