2

对于我的创业公司,我自己跟踪一切,而不是依赖谷歌分析。这很好,因为我实际上可以拥有 ips 和用户 ID 以及所有内容。

这一直很好,直到我的跟踪表增加了大约 200 万行。该表称为acts,并记录:

  • ip
  • 网址
  • 笔记
  • 帐户ID

...在可用的情况下。

现在,尝试做这样的事情:

SELECT COUNT(distinct ip) 
  FROM acts
  JOIN users ON(users.ip = acts.ip) 
 WHERE acts.url LIKE '%some_marketing_page%';

基本上永远不会结束。我切换到这个:

SELECT COUNT(distinct ip) 
  FROM acts
  JOIN users ON(users.ip = acts.ip) 
 WHERE acts.note = 'some_marketing_page';

但它仍然很慢,尽管有一个索引。

我显然不是 mysql 的专业人士。我的问题是:

拥有大量数据的公司如何跟踪漏斗转化率之类的东西?是否可以在 mysql 中做而我只是缺少一些知识?如果没有,我可以阅读哪些书籍/博客来了解网站如何做到这一点?

4

3 回答 3

1

为什么要加入?如果我们可以假设在没有用户关联记录的情况下没有 IP 使其成为行为,那么您不需要加入:

SELECT COUNT(distinct ip) FROM acts
WHERE acts.url LIKE '%some_marketing_page%';

如果您确实需要 JOIN,则可能需要先从行为中选择不同的 IP,然后将这些结果 JOIN 给用户(您必须查看执行计划并进行试验,看看这是否更快)。

其次,带有前导通配符的 LIKE 将导致对行为进行全表扫描,并且还需要进行一些昂贵的文本搜索。您有三个选择来改善这一点:

  1. 在存储之前将 url 分解为组件部分,以便搜索与列值完全匹配。

  2. 要求搜索词出现在 url 字段的开头,而不是中间。

  3. 研究一个全文搜索引擎,该引擎将以这样的方式索引 url 字段,即使是内部 LIKE 搜索也可以针对索引执行。

最后,在搜索acts.notes 的情况下,如果notes 上的索引不能提供足够的搜索改进,我会考虑计算和存储notes 上的整数散列并搜索它。

于 2009-11-25T02:47:14.287 回答
1

在走向“可敬”的同时,200 万行对于一张表来说仍然是一个相对较小的大小。(因此通常可以实现更快的性能)

正如您所发现的,前端通配符效率特别低,如果该用例对您的应用程序很常见,我们将不得不为此找到解决方案。

可能只是您没有正确的索引集。然而,在我继续之前,我想强调,虽然索引通常会使用各种 SELECT 语句来提高 DBMS 性能,但它系统地对“CUD”操作的性能(即使用 SQL CREATE/INSERT、UPDATE , DELETE 动词,即写入数据库而不是读取数据库的查询)。在某些情况下,索引对“写入”查询的负面影响可能非常显着。

我特别强调索引的矛盾性质的原因是,您的应用程序似乎将大量数据收集作为其操作的正常部分,并且您需要注意可能的降级,因为 INSERT 查询会变慢. 一种可能的替代方法是将数据收集到一个相对较小的表/数据库中,没有或只有很少的索引,并定期将数据从该输入数据库导入到进行实际数据挖掘的数据库中。(导入后,行可能会从“输入数据库”中删除,使其 INSERT 功能保持小而快。)

另一个问题/问题是关于演员表中一行的宽度(列数和这些列的宽度之和)。糟糕的性能可能与行太宽有关,导致表的叶节点中的行太少,因此树结构的深度超出了需要。

回到索引......
鉴于问题中的几个查询,您似乎可以从 ip + note 索引(至少按此顺序使用这两个键创建的索引)中受益。对索引情况的全面分析,坦率地说,无法在这里完成对数据库模式的可能审查(没有足够的信息......),但这样做的一般过程是列出最常见的用例和查看哪些数据库索引可以帮助解决这些情况。可以使用 mySQL 命令 EXPLAIN 深入了解如何处理特定查询,最初或添加索引后。

规范化或非道德化(或两者兼而有之!)通常也是提高采矿作业性能的可行想法。

于 2009-11-25T02:33:10.010 回答
0

尝试在您的查询上运行“EXPLAIN PLAN”并查看是否有任何表扫描。

这应该是左连接吗?

也许这个网站可以提供帮助。

于 2009-11-25T02:33:53.067 回答