gpt4 book ai didi

具有多个索引的表的 mysql 索引优化,这些索引索引了一些相同的列

转载 作者:可可西里 更新时间:2023-11-01 07:06:44 25 4
gpt4 key购买 nike

我有一个表,用于存储有关第三方网站访问者 session 的一些基本数据。这是它的结构:

id, site_id, unixtime, unixtime_last, ip_address, uid

有四个索引:idsite_id/unixtimesite_id/ip_addresssite_id/uid

我们查询此表的方式有很多种,而且都是特定于 site_id 的。带有 unixtime 的索引用于显示给定日期或时间范围内的访问者列表。其他两个用于查找来自 IP 地址或“uid”(为每个访问者创建的唯一 cookie 值)的所有访问,以及确定这是新访问者还是回访者。

显然,将 site_id 存储在 3 个索引中对于写入速度和存储来说都是低效的,但我认为没有办法解决它,因为我需要能够快速查询给定特定 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 的行。这不一定是超快的,但可以接受的快。但是假设我们有一个每天有 500,000 名访问者的网站,并且某个特定的访问者喜欢这个网站并且每天去那里 10 次。现在他们碰巧第一次访问同一数据库服务器上的另一个站点。上面的查询可能需要相当长的时间来搜索此 UID 的所有可能的数千行,这些行分散在整个磁盘上,因为它找不到与此站点 ID 对应的行。

任何关于使它尽可能高效的见解将不胜感激:)

更新 - 这是 MySQL 5.0 的 MyISAM 表。我关心的是性能和存储空间。这张表读写都很重。如果我必须在性能和存储之间做出选择,我最关心的是性能 - 但两者都很重要。

我们在服务的所有领域都大量使用 memcached,但这不是不关心数据库设计的借口。我希望数据库尽可能高效。

最佳答案

I don't really understand B-trees besides some very basic stuff, but it's more efficient to have the left-most column of an index be the one with the least variance - correct?

您需要了解 B 树索引的一个重要属性:可以(有效地)搜索全键的任意 prefix,但不能搜索 后缀。如果你有一个索引 site_ip(site_id, ip) , 然后你要求 where ip = 1.2.3.4 , MySQL 不会使用 site_ip 索引。如果你有 ip_site(ip, site_id) , 那么 MySQL 就可以使用 ip_site 索引了。

您还应该了解 B 树索引的第二个属性:它们是有序的。 B 树索引可用于类似 where site_id < 40 的查询.

还有一个磁盘驱动器的重要特性需要牢记:顺序读取成本低,寻道成本低。如果使用了任何不在索引中的列,MySQL 必须从表数据中读取该行。这通常是一种寻找,而且速度很慢。因此,如果 MySQL 认为它最终会像这样读取表的一小部分,它就会忽略索引。一次大表扫描(顺序读取)通常比随机读取表中的百分之几的行要快。

顺便说一句,这同样适用于通过索引查找。在 B 树中查找 key 实际上可能需要进行几次查找,因此您会发现 WHERE site_id > 800 AND ip = '1.2.3.4'不能使用 site_ip索引,因为每个 site_id 都需要多个索引来查找该站点的 1.2.3.4 记录的开头。 ip_site但是,将使用索引。

最终,您将不得不自由使用基准测试和 EXPLAIN找出适合您数据库的最佳索引。请记住,您可以根据需要自由添加和删除索引。非唯一索引不是数据模型的一部分;它们只是一种优化。

PS:同样是Benchmark InnoDB,它往往有更好的并发性能。与 PostgreSQL 相同。

关于具有多个索引的表的 mysql 索引优化,这些索引索引了一些相同的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2588932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com