Tenho uma tabela de valores únicos ( domains_unique
), com coluna domain
varchar(255), com mais de 20 mil registros.
Qual é a maneira mais rápida de inserir na tabela, mantendo a domain
restrição exclusiva?
Eu decidi que a consulta deveria ser:
INSERT IGNORE INTO domains_table (domain) VALUE ('domain.com')
Devo criar domain
a chave primária ou devo torná-la um índice exclusivo?
Método de chave primária:
CREATE TABLE `domains_unique`
(
`domain` varchar(255) NOT NULL
PRIMARY KEY (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE = utf8_general_ci;
Método de índice exclusivo:
CREATE TABLE `domains_unique`
(
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`domain` varchar(255) NOT NULL
PRIMARY KEY (`id`),
UNIQUE KEY unique_index (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE = utf8_general_ci;
Além disso, quanto mudaria o CHARSET
e afetaria COLLATION
o ascii_bin
desempenho?
obs:
Eu usaria INSERT DELAYED IGNORE INTO
, mas preciso saber se a linha específica (domínio) foi inserida, isso também exclui a inserção em massa.
ATUALIZAR:
Como prometido, os resultados dos benchmarks:
INSERIR 5k linhas únicas com 4,5k novas linhas em uma tabela de 1 mil linhas, uma linha por vez:
- Método de chave primária: 5,7 segundos
- Método de índice exclusivo: 6,3 segundos
Para testar o dimensionamento, também testei o método Unique Index em uma tabela de 40mil linhas e demorou 45,8 s
Pela sua pergunta, não tenho certeza se você está inserindo vários valores por consulta, mas definitivamente deveria. Com o MyISAM como mecanismo, não deve haver diferença de desempenho entre o índice ser
UNIQUE
ouPRIMARY
; MyISAM não os trata de forma diferente neste caso. Se você estivesse usando o InnoDB, no entanto, haveria uma diferença, pois ele armazena os dados na ordem da chave primária. Se você não precisar daid
coluna, removê-la e criardomain
a chave primária ajudaria no desempenho.Alterar o agrupamento deve ajudar, pois
ascii
é muito mais simples do queutf8
, mas você pode querer usarascii_general_ci
em vez deascii_bin
, pois os nomes de domínio não diferenciam maiúsculas de minúsculas.Uma outra maneira de fazer as consultas seria obter o número de linhas
INSERT DELAYED
, liberar as gravações atrasadas e, em seguida, obter a nova contagem de linhas. A diferença nas contagens seria a mesma das linhas afetadas. No entanto, não acho que isso seria significativamente mais rápido, mas tornaria o processo mais complexo.