2010-06-09 7 views
2

J'ai 2 bases de données et j'ai besoin de lier des informations entre deux grandes tables (plus de 3M entrées chacune, en croissance continue). La 1ère base de données possède une table 'pages' qui stocke diverses informations sur les pages web, et inclut l'URL de chacune. La colonne 'URL' est un varchar (512) et n'a pas d'index.Mysql InnoDB optimisation des performances et indexation

La 2ème base de données a une table 'urlHops' définie comme:

CREATE TABLE urlHops ( dest varchar (512) NOT NULL, src varchar (512) NULL DEFAULT, horodatage timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY dest_key (dest), KEY src_key (src) ) MOTEUR = InnoDB DEFAULT CHARSET = latin1

Maintenant, j'ai besoin de lancer des requêtes (efficacement) comme ceci: sélectionnez p.id, p.URL de db1.pages p, db2.urlHops u où u.src = p.URL et u.dest =? Dans un premier temps, j'ai pensé à ajouter un index sur les pages (URL). Mais c'est une colonne très longue, et je publie déjà beaucoup de INSERTs et UPDATEs sur la même table (bien plus que le nombre de SELECT que je ferais en utilisant cet index).

D'autres solutions possibles que je pensais être: -adding une colonne aux pages, en stockant le hachage md5 de l'URL et en l'indexant; De cette façon, je pourrais faire des requêtes en utilisant le md5 de l'URL, avec l'avantage d'un index sur une colonne plus petite. : ajoute une autre table contenant uniquement l'ID de la page et l'URL de la page, indexant les deux colonnes. Mais c'est peut-être un gaspillage d'espace, n'ayant que l'avantage de ne pas ralentir les insertions et mises à jour que j'exécute sur les 'pages'.

Je ne veux pas ralentir les insertions et les mises à jour, mais en même temps je serais capable de faire les requêtes sur l'URL efficacement. Aucun conseil? Ma principale préoccupation est la performance; Si nécessaire, gaspiller de l'espace disque n'est pas un problème.

Merci, ce qui

Davide

+0

@Gary: J'ai essayé de le faire avant, mais urlHops est une table sur laquelle j'insère des données à très haute vitesse, donc je ne peux pas la diviser en deux (je dois essentiellement y ajouter des couples de src et dest URL). Si je le divise comme ça, alors les inserts sur lui ralentissent trop pour mes besoins. –

Répondre

0

Si les pages à URL est une relation 1 à 1 et que la table a un identifiant unique (clé primaire?), Vous pouvez stocker cette valeur identifiant dans la Les champs src et dest dans la table urlHops au lieu de l'URL complète.

Cela rendrait l'indexation et les jointures beaucoup plus efficaces.

+0

va essayer avec cette solution, même si je n'ai pas de mapping 1 à 1 ... je m'attends à ce que ça marche plutôt bien –

0

Je créerais une table page_url avec une clé primaire auto-inc integer et votre valeur d'URL. Ensuite, mettez à jour Pages et urlHops pour utiliser page_url.id. Vos urlHops deviendraient (dest int, src int, ...)
Votre tableau Pages remplacerait l'URL par pageid.

Index page_url.url champ, et vous devriez être bon à faire.

3

La suggestion de hachage MD5 que vous aviez est très bonne - elle est documentée dans la version haute performance de MySQL 2nd Ed.Il y a quelques astuces pour faire fonctionner:

CREER urls TABLE ( id NOT NULL auto_increment clé primaire, url varchar (255) non null, url_crc32 INT UNSIGNED non nul, INDEX (url_crc32) ) ;

requêtes Sélectionnez doivent ressembler à ceci:

SELECT * FROM urls OÙ url = 'http://stackoverflow.com 'ET url_crc32 = crc32 (' http://stackoverflow.com');

L'url_crc32 est conçu pour fonctionner avec l'index, y compris l'URL de la clause WHERE conçue pour empêcher les collisions de hachage.

Je recommanderais probablement crc32 sur md5. Il y aura quelques collisions de plus, mais vous avez plus de chances d'ajuster tout l'index en mémoire.