2010-06-09 92 views
2

我有2个数据库,我需要链接两个大表(每个超过3M条目,不断增长)之间的信息。 第一个数据库有一个表“页面”,用于存储有关网页的各种信息,并包含每个网页的URL。列'URL'是一个varchar(512)并且没有索引。Mysql InnoDB性能优化和索引

的第二数据库具有定义为表 'urlHops':

CREATE TABLE urlHopsdest VARCHAR(512)NOT NULL, src VARCHAR(512)DEFAULT NULL, timestamp时间戳NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY dest_keydest) KEY src_keysrc) )ENGINE = InnoDB的默认字符集= LATIN1

现在,我基本上需要发出(高效)这样的查询: 从db1.pages中选择p.id,p.URL,db2.urlHops u其中u.src = p.URL和u.dest =?

起初,我想在页面(URL)上添加一个索引。但是这是一个非常长的列,我已经在同一张表上发布了很多INSERT和UPDATE(比使用这个索引的选择的数量要多)。

我认为的其他可能的解决方案是: - 为页面添加一列,存储URL的md5散列并将其编入索引;通过这种方式,我可以使用URL的md5进行查询,并且可以在较小的列上使用索引。 - 添加另一个只包含页面标识和页面URL的表格,为两列编制索引。但是,这可能是浪费空间,只有不减慢我在'页面'上执行的插入和更新的优势。

我不想放慢插入和更新,但同时我可以有效地对URL进行查询。有什么建议?我最关心的是表现;如果需要,浪费一些磁盘空间不是问题。

谢谢你,至于

达维德

+0

@Gary:我之前试过这样做,但是urlHops是我以极高的速度插入数据的表,所以我不能将它分成两部分(我基本上需要追加到它的src和dest夫妇URL)。如果我像这样分割它,那么它上面的插入就会减慢我的需要。 – 2010-06-09 21:32:09

回答

0

如果页面,URL的是1对1的关系,并且表有唯一的ID(主键?),你可以存储值在该ID在urlHops表中的src和dest字段而不是完整的URL。

这将使索引和联接更高效。

+0

即使我没有1对1的映射,也会尝试使用此解决方案......我希望它工作得相当好 – 2010-06-09 22:35:41

0

我会创建一个包含auto-inc整数主键和你的URL值的page_url表。然后更新Pages和urlHops以使用page_url.id。

您的urlHops将变为(dest int,src int,...)
Your Pages表将用pageid替换url。

索引page_url.url字段,你应该很好去。

3

你的MD5哈希建议非常好 - 它被记录在High Performance MySQL 2nd Ed中。有一些技巧来获得它的工作:

CREATE TABLE网址( ID NOT NULL主键AUTO_INCREMENT, 网址为varchar(255)NOT NULL, url_crc32 INT UNSIGNED NOT NULL, INDEX(url_crc32) ) ;

选择查询必须是这样的:

SELECT * FROM网址,其中URL = 'http://stackoverflow.com 'AND url_crc32 = CRC32(' http://stackoverflow.com');

url_crc32被设计为与索引一起使用,包括WHERE子句中的url用于防止哈希冲突。

我可能会推荐crc32超过md5。将会有更多的碰撞,但你有更高的机会将所有的索引放在内存中。