Tarantool SQL медленнее SQLite??

178 views
Skip to first unread message

Александр

unread,
Jan 13, 2020, 4:27:02 AM1/13/20
to tarantool-ru
Здравствуйте, разбираюсь в Тарантуле и решил провести тесты по скорости, но обнаружил очень неприятную штуку - используя SQL, Tarantool работает медленнее SQLite :\

Я создал базу в 1кк записей и протестировал запросы.

#!/usr/bin/env tarantool

box.cfg {
pid_file   = "tarantool_test/pid.pid",
    log        = "tarantool_test/tarantool.log",
    wal_dir    = "tarantool_test",
    memtx_dir  = "tarantool_test",
    vinyl_dir  = "tarantool_test"
}

--box.execute("pragma sql_default_engine = 'vinyl'");
box.execute("CREATE TABLE IF NOT EXISTS tester (s1 INT PRIMARY KEY, s2 VARCHAR(10))");

local function string_function()
   local random_number
   local random_string
   random_string = ""
   for x = 1,10,1 do
random_number = math.random(65, 90)
random_string = random_string .. string.char(random_number)
   end
   return random_string
end;

local function main_function()
   local string_value, t, sql_statement
   for i = 1,1000000,1 do
string_value = string_function()
sql_statement = "INSERT INTO tester VALUES (" .. i .. ",'" .. string_value .. "')"
box.execute(sql_statement)
   end
end;

local start_time = os.clock();
main_function();
local end_time = os.clock();
print('insert done in ' .. end_time - start_time .. ' seconds');

start_time = os.clock()
box.execute("SELECT * FROM tester WHERE s1=736")
end_time = os.clock()
print('SELECT index done in ' .. end_time - start_time .. ' seconds')

start_time = os.clock()
box.execute("SELECT * FROM tester WHERE s2 LIKE 'QFML%'")
end_time = os.clock()
print('SELECT LIKE done in ' .. end_time - start_time .. ' seconds')


И вот что получается.

memtx:
tarantool test2.lua
 insert 
done in 37.64 seconds
 SELECT index 
done in 0 seconds
 SELECT LIKE 
done in 0.61 seconds

vinyl:
tarantool test2.lua
 insert
done in 41.63 seconds
 SELECT index
done in 0 seconds
 SELECT LIKE
done in 3.69 seconds

Аналогичные запросы в sqlite на том же железе:
SQLite version 3.7.17
sqlite> .timer on

sqlite
> SELECT * FROM tester WHERE s1=736;
CPU
Time: user 0.000118 sys 0.000002

sqlite
> SELECT * FROM tester WHERE s2 LIKE 'QFML%';
CPU Time: user 0.883653 sys 0.016357

Пожалуйста, скажите что это неправда и я где-то ошибся :(

Александр

unread,
Jan 13, 2020, 4:40:42 AM1/13/20
to tarantool-ru
Добавлю, что тесты без SQL (на Lua) я не проводил, т.к. просто еще не разбираюсь, как составлять запросы. Мой вопрос пока без ответа...

Александр

unread,
Jan 13, 2020, 4:51:27 AM1/13/20
to tarantool-ru
PS.
Tarantool 2.2.2-4-g4f8ac59

Konstantin Osipov

unread,
Jan 13, 2020, 5:42:31 AM1/13/20
to tarant...@googlegroups.com
* Александр <nakaz...@gmail.com> [20/01/13 12:27]:

Это правда.

В целом проблема в том что внутреннее представление данных в
tarantool не заточено на query processing, который сканирует много
данных, а на обработку однострочных запросов.

Вот например тикет отражающий часть проблемы:

https://github.com/tarantool/tarantool/issues/3891
> --
> Вы получили это сообщение, поскольку подписаны на группу tarantool-ru.
>
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес tarantool-ru...@googlegroups.com.
> Просмотреть это обсуждение в Сети можно по адресу https://groups.google.com/d/msgid/tarantool-ru/b102e476-9604-4769-844b-829479f48b75%40googlegroups.com.


--
Konstantin Osipov, Moscow, Russia

Кирилл Юхин

unread,
Jan 13, 2020, 6:06:48 AM1/13/20
to tarantool-ru
Добрый день!
Насколько я вижу, медленнее только сканирование на Виниле.
Дело в том, что Винил - движок основанный на технологии LSM-деревьев.
Он оптимизирован на записи в большей степени, чем на чтения. 

Александр

unread,
Jan 13, 2020, 6:20:55 AM1/13/20
to tarantool-ru
Благодарю за ответы! Тогда попробую поизучать запросы с помощью Lua, т.к. из-за этой проблемы нет смысла использовать SQL в Виниле. Тем более, что данных в базе должно быть очень много.

Если можно, то напишите, пожалуйста, пример, как выполнить следующие запросы, не используя sql:

SELECT * FROM tester WHERE s2 LIKE 'QFML%';

UPDATE tester SET s2
='13123' WHERE s2='DSJNBGTYFE';

Уже неделю читаю/изучаю, но пока никак не пойму, как это можно реализовать.

Заранее благодарен.

Konstantin Osipov

unread,
Jan 13, 2020, 6:22:40 AM1/13/20
to tarant...@googlegroups.com
* Кирилл Юхин <kyu...@gmail.com> [20/01/13 14:07]:
> Насколько я вижу, медленнее только сканирование на Виниле.
> Дело в том, что Винил - движок основанный на технологии LSM-деревьев.
> Он оптимизирован на записи в большей степени, чем на чтения.

И как же эта "оптимизация" замедляет сканирование?

Может быть дело в том что на прочитанный тапл винил создаёт копию в
malloc, а потом ещё в этой копии нужное поле нужно найти линнейным
сканированием с начала тапла?

Александр

unread,
Jan 13, 2020, 2:50:46 PM1/13/20
to tarantool-ru
Оказывается, в tarantool sql, если в запросе используется LIKE и поиск выполняется с начала строки, то индексы-то работают! :) А в sqlite нет.

box.execute("CREATE INDEX s2_idx ON tester (s2)");

box.execute("SELECT * FROM tester WHERE s2 LIKE 'QFML%'");

А это, в свою очередь, перекрывает изначальную проблему)

Кирилл Юхин

unread,
Jan 14, 2020, 3:09:55 AM1/14/20
to tarantool-ru
Нужно только иметь ввиду, что поиск по индексу работает не для всех паттернов.
Это видно если вызвать EXPLAIN для запроса. Например:

tarantool> \set language sql
---
- true
...

tarantool
> EXPLAIN QUERY PLAN SELECT * FROM tester WHERE s2 LIKE 'QFML%'
---
- metadata:
 
- name: selectid
    type
: integer
 
- name: order
    type
: integer
 
- name: from
    type
: integer
 
- name: detail
    type
: text
  rows
:
 
- [0, 0, 0, 'SEARCH TABLE TESTER USING COVERING INDEX S2_IDX (S2>? AND S2<?) (~16384
      rows)'
]
...

tarantool
> EXPLAIN QUERY PLAN SELECT * FROM tester WHERE s2 LIKE '%QFML%'
---
- metadata:
 
- name: selectid
    type
: integer
 
- name: order
    type
: integer
 
- name: from
    type
: integer
 
- name: detail
    type
: text
  rows
:
 
- [0, 0, 0, 'SCAN TABLE TESTER (~983040 rows)']
...



Александр

unread,
Jan 14, 2020, 12:34:43 PM1/14/20
to tarantool-ru
Не знаю куда писать и стоит ли вообще это писать? Может вы и так в курсе..

Count в sql также работает медленно:
select count(s1) from tester;

При этом, в lua'шной версии базы немного быстрее:
box.space.tester:count(1, {iterator='GE'})

А так идеально:
box.space.tester:len()


Reply all
Reply to author
Forward
0 new messages