[SP-pm] DBIx::Class
Eden Cardim
eden at insoli.de
Thu Sep 19 06:53:30 PDT 2013
>>>>> "Lucas" == Lucas Oliveira <lucasmateus.oliveira em gmail.com> writes:
Lucas> Show, sobre o MD5 que falei aqui tem um benchmark recente e
Lucas> bacana.
Lucas> http://www.big.info/2013/05/some-useful-mysql-database-md5-binary16.html
É MUITO estranho que uma consulta de look-up simples leve 56 segundos,
mesmo pro mysql e mesmo com 2M registros. Tem algo errado com esse
teste aí.
Fiz um benchmark similar aqui com postgres 9.1.9:
Um varchar de 10M caracteres, que é relativamente grande.
edenc=# create table test (id serial primary key, mystring varchar(10000000));
NOTICE: CREATE TABLE will create implicit sequence "test_id_seq" for serial column "test.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test"
CREATE TABLE
Time: 177.671 ms
Povoei 2M colunas com textos de tamanhos aleatórios:
edenc=# insert into test (mystring) select repeat(n::text, (random() * 1000 + 1)::int) from generate_series(1,2000000) as n;
INSERT 0 2000000
Time: 199198.163 ms
Achei um registro que coubesse na tela:
edenc=# select mystring from test where length(mystring) < 100 limit 1;
mystring
--------------------------------------------------------------------------------------
198872419887241988724198872419887241988724198872419887241988724198872419887241988724
(1 row)
Time: 2.437 ms
E consultei a tabela sem usar índice:
edenc=# select mystring from test where mystring = '198872419887241988724198872419887241988724198872419887241988724198872419887241988724';
mystring
--------------------------------------------------------------------------------------
198872419887241988724198872419887241988724198872419887241988724198872419887241988724
(1 row)
Time: 503.553 ms
Depois criei o índice:
edenc=# create index on test (mystring);
CREATE INDEX
Time: 369215.286 ms
E repeti a consulta:
edenc=# select mystring from test where mystring = '198872419887241988724198872419887241988724198872419887241988724198872419887241988724';
mystring
--------------------------------------------------------------------------------------
198872419887241988724198872419887241988724198872419887241988724198872419887241988724
(1 row)
Time: 8.819 ms
Obviamente, tem um fator distorcendo esses resultados, que é o page
cache do kernel e os shared buffers do pg que foram construídos
durante a escrita da tabela e o shared buffer cache do pg. Então eu
reiniciei a máquina pra garantir que não havia cache de kernel nem de
buffer:
edenc=# select mystring from test where mystring = '198872419887241988724198872419887241988724198872419887241988724198872419887241988724';
mystring
--------------------------------------------------------------------------------------
198872419887241988724198872419887241988724198872419887241988724198872419887241988724
(1 row)
Time: 336.108 ms
E uma segunda query:
edenc=# select mystring from test where mystring = '198872419887241988724198872419887241988724198872419887241988724198872419887241988724';
mystring
--------------------------------------------------------------------------------------
198872419887241988724198872419887241988724198872419887241988724198872419887241988724
(1 row)
Time: 0.380 ms
Que é bem mais rápida porque na segunda consulta, as páginas
relevantes da tabela (e *não* o resultado) foram cacheadas.
Obviamente, não é um teste perfeito, mas dá pra ter uma idéia da
falácia. Enfim, chaves artificiais como otimização são quase sempre
desnecessárias. O motivo é que com o índice certo (uma árvore de
busca), num campo unique, o banco de dados *nunca* vai ter que
comparar a string inteira. Olhem por exemplo o plano que é gerado
quando se trata de um like:
edenc=# explain select mystring from test where mystring like '1111%';
QUERY PLAN
------------------------------------------------------------------------------------------
Index Scan using test_mystring_idx on test (cost=0.00..3384.37 rows=200 width=359)
Index Cond: (((mystring)::text >= '1111'::text) AND ((mystring)::text < '1112'::text))
Filter: ((mystring)::text ~~ '1111%'::text)
(3 rows)
More information about the SaoPaulo-pm
mailing list