Tenir compte de cette requête:performances SQL sur la correspondance multiple identifiant et un JOIN
SELECT DISTINCT (linkindex_tags.link_id)
, links_sorted.link_title
, links_sorted.link_url
FROM linkindex_tags
INNER JOIN links_sorted ON links_sorted.link_id = linkindex_tags.link_id
ORDER BY
(
IF (word_id = 400, 1,0)+
IF (word_id = 177, 1,0)+
IF (word_id = 114, 1,0)+
IF (word_id = 9, 1,0)+
IF (word_id = 270, 1,0)+
IF (word_id = 715, 1,0)+
IF (word_id = 279, 1,0)+
IF (word_id = 1, 1,0)+
IF (word_id = 1748, 1,0)
) DESC
LIMIT 0,15;
Ainsi, la recherche pour les matchs à une série de son et odering word_id par le score de ces matchs (par exemple, trouver un lien avec 5 word_ids puis il est un score de 5)
La table linkindex_tags est actuellement 552,196 lignes (33 Mo) mais expan à plusieurs millions Le tableau link_sorted est actuellement 823600 (558MB - OBV plus de données par ligne) lignes, mais également étendre plus . La table linkindex_tags est susceptible d'être environ 8-12 fois plus grande que links_sorted.
Temps d'exécution: 7,069 secondes sur une machine Windows 7 Core i3 locale. Mon serveur est CentOs 64bit RAM 8 Go Intel Xeon 3470 (Quad Core) - donc cela aidera dans la question un peu comme je peux attribuer une allocation de RAM décent.
Il court lentement et se demandait si mon approche était erronée. Voici les bits lents de la rupture du profil:
copie au TMP tableau - (heure) 3,88124 - (%) 55,08438
copie au TMP tableau sur le disque - (heure) 2,683123 - (%) 8,08010
convertir PGRPI à MyISAM - (temps) 0,37656 - (%) 5,34432
Voici le EXPLIQUER:
id - 1
select_type - SIMPLE
table - linkindex_tags
type - index
possible_keys - link_id,link_id_2
key - link_id
key_len - 8
ref - \N
rows - 552196
Extra - Using index; Using temporary; Using filesort
2nd row
id - 1
select_type - SIMPLE
table - links_sorted
type - eq_ref
possible_keys - link_id
key - link_id
key_len - 4
ref - flinksdb.linkindex_tags.link_id
rows - 1
Extra -
Et enfin, le schéma de 2 table:
CREATE TABLE IF NOT EXISTS `linkindex_tags` (
`linkindex_tag_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`link_id` int(10) unsigned NOT NULL,
`word_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`linkindex_tag_id`),
UNIQUE KEY `link_id` (`link_id`,`word_id`),
KEY `link_id_2` (`link_id`),
KEY `word_id` (`word_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
CREATE TABLE IF NOT EXISTS `links_sorted` (
`link_sorted_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`site_id` int(10) unsigned NOT NULL,
`link_id` int(10) unsigned NOT NULL,
`link_title` char(255) NOT NULL,
`link_duration` char(20) NOT NULL,
`link_url` char(255) NOT NULL,
`active` tinyint(4) NOT NULL,
PRIMARY KEY (`link_sorted_id`),
UNIQUE KEY `link_id` (`link_id`),
KEY `link_title` (`link_title`,`link_url`,`active`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
Avoir à coller avec INT, car il peut entrer une plage plus grande que MEDIUMINT. Sans la jointure, juste obtenir les ids la requête est rapide maintenant j'ai augmenté certains paramètres de MySQL. Je ne connais pas trop les paramètres MySQL et leurs effets, donc si vous avez besoin de moi pour changer quelques paramètres et faire des tests par tous les moyens, c'est parti!
Oh et moi avons joué avec les paramètres de mysql.ini pour qu'ils soient comme ça - juste deviner et jouer vraiment!
key_buffer = 512M
max_allowed_packet = 1M
table_cache = 512M
sort_buffer_size = 512M
net_buffer_length = 8K
read_buffer_size = 512M
read_rnd_buffer_size = 512K
Comment puis-je accélérer cette requête?
Je ne sais pas si cela vous donnera beaucoup d'avantages de performance, mais vous pouvez réécrire tout ce tri complexe en ceci: 'commande par word_id en (400, 177, 114, 9, 270, 715, 279, 1, 1748) desc' – Karolis
Merci pour cela, sauf si je me trompe, ne marquera pas les matchs .. – dolyth
effectivement ignorer cela, Johan a expliqué cela – dolyth