我有一个表,存储有关第三方网站上的访问者会话的一些基本数据.这是它的结构:
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值),以及确定这是新访问者还是返回访问者.
显然,将site_id存储在3个索引中对于写入速度和存储都是低效的,但我认为没办法,因为我需要能够快速查询给定特定site_id的数据.
有关提高效率的想法吗?
除了一些非常基本的东西之外,我真的不了解B树,但是让索引的最左列是方差最小的那个更有效 - 对吗?因为我认为site_id是ip_address和uid的索引的第二列,但我认为这会使索引效率降低,因为IP和UID的变化将超过站点ID,因为我们只有大约8000每个数据库服务器的唯一站点,但每天在所有~8,000个站点中有数百万个唯一访问者.
我还考虑过完全从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,但这并不是不关心数据库设计的借口.我希望数据库尽可能高效.