我有一张表,其中存储有关第三方网站上的访问者会话的一些基本数据。这是它的结构:对具有索引某些相同列的多个索引的表的mysql索引优化
id, site_id, unixtime, unixtime_last, ip_address, uid
有四个指标:id
,site_id/unixtime
,site_id/ip_address
和site_id/uid
有许多不同类型的,我们查询此表的方式,和所有的人所特有的SITE_ID。带有unixtime的索引用于显示给定日期或时间范围内的访问者列表。另外两个用于查找来自IP地址或“uid”(为每个访客创建的唯一cookie值)的所有访问,以及确定这是新访问者还是返回访问者。
显然,在3个索引内部存储site_id对于写入速度和存储都是低效的,但我没有办法解决它,因为我需要能够快速查询给定特定site_id的这些数据。
任何想法使这更高效?
除了一些非常基本的东西外,我不太了解B树,但是如果索引最左边的一列是最小方差的那一列更有效 - 对吗?因为我认为将site_id作为ip_address和uid索引的第二列,但我认为这会使索引效率降低,因为IP和UID会比站点ID更大,因为我们只有大约8000每个数据库服务器都有独特的网站,但每天大约有8000个网站的数百万独立访问者。
我也考虑彻底从IP和UID索引中删除site_id,因为同一个访问者转到共享相同数据库服务器的多个站点的几率很小,但是在发生这种情况的情况下,我担心确定这是否是该site_id的新访问者可能会很慢。该查询会是这样的:
select id from sessions where uid = 'value' and site_id = 123 limit 1
...因此,如果这个来访者以前访问过该网站,那就只需要找到这个SITE_ID一行才停下。这不会超快,但可接受的速度很快。但是,假设我们有一个网站每天可以获得50万个访问者,并且特定的访问者喜欢这个网站,并且每天去那里访问10次。现在他们碰巧第一次碰到同一台数据库服务器上的另一个站点。上述查询可能需要相当长的时间来搜索这个UID的所有潜在数千行,遍布整个磁盘,因为它不会为这个站点ID找到一个。
进行此尽可能高效任何有识之士将不胜感激:)
更新 - 这是与MySQL 5.0中的MyISAM表。我的担忧既有性能又有存储空间。这个表格既读又重写。如果我必须在性能和存储之间做出选择,我最关心的是性能 - 但两者都很重要。
我们在我们服务的所有领域大量使用memcached,但这不是不关心数据库设计的借口。我希望数据库尽可能高效。
存储引擎? mysql版本?你想如何提高这个效率 - 明智的使用磁盘或者性能?你有没有解决实际问题,或者这只是一个修辞问题? – ggiroux 2010-04-07 00:39:26
mysql 5.0,myisam引擎。我既关心存储空间又关注性能,因为这既是一个读写表,也是一个重写表。是的,实际的问题。 :) – Sean 2010-04-07 00:46:47
你读过高性能MySQL吗? – 2010-05-07 11:37:22