【发布时间】:2012-10-30 08:17:20
【问题描述】:
我在 InnoDB 表中的列 a VARCHAR(255), b INT 上有一个索引。给定两个 a,b 对,我可以使用 MySQL 索引来确定来自 c 程序的对是否相同(即不使用 strcmp 和数值比较)?
- MySQL InnoDB 索引存储在文件系统的什么位置?
- 可以从单独的程序中读取和使用它吗?格式是什么?
- 如何使用索引来确定两个键是否相同?
注意:这个问题的答案应该是 a) 提供一种访问 MySQL 索引的方法以完成此任务,或者 b) 解释为什么实际上不能以这种方式访问/使用 MySQL 索引。特定于平台的答案很好,我使用的是 Red Hat 5.8。
下面是这个问题的先前版本,它提供了更多的上下文,但似乎分散了实际问题的注意力。我知道在 MySQL 中还有其他方法可以完成此示例,我提供了两种方法。这不是关于优化的问题,而是考虑到存在于许多不同动态生成的查询中的复杂性。
我可以使用带有子分组的子选择来完成我的查询,例如
SELECT c, AVG(max_val)
FROM (
SELECT c, MAX(val) AS max_val
FROM table
GROUP BY a, b) AS t
GROUP BY c
但我已经编写了一个 UDF,它允许我通过单个选择来完成,例如
SELECT b, MY_UDF(a, b, val)
FROM table
GROUP by c
这里的关键是我将字段a 和b 传递给UDF,并且我手动管理每个组中的a,b 子组。列 a 是一个 varchar,因此这涉及到调用 strncmp 以检查匹配项,但速度相当快。
但是,我有一个索引my_key (a ASC, b ASC)。我可以访问和使用 MySQL 索引,而不是手动检查 a 和 b 上的匹配项吗?也就是说,我可以在 my_key 中获取给定行的索引值,还是在 c(UDF 内部)中获取 a,b 对?如果是这样,是否可以保证索引值对于任何值a,b 都是唯一的?
我想调用MY_UDF(a, b, val),然后从UDF中查找c中的mysql索引值(a,b)。
【问题讨论】:
-
@Clockwork-Muse 我知道如何用 C 编写扩展,它被称为 udf。我专门询问如何从 udf 访问 mysql 索引。你是对的,将子选择放在其他地方不是解决方案。
-
承认我从来没有写过:不,我不这么认为。或者至少,如果不写一些部署特定的东西(而且真的很hacky) - 你可能不得不硬编码表的名称。鉴于functions seems to work 的调用顺序,您实际上甚至看不到实际的表对象(或索引)本身,您会从优化器中获得预先排序和预先分组的行。就个人而言,无论如何我都不想这样做,因为它允许更好的未来灵活性(以防应该选择不同的索引)。
-
您想通过在最里面的查询中选择未分组和未聚合的
c来实现什么?您能否提供一些示例数据和所需的输出? -
听起来您正在寻找一种接近于 hack 的解决方案。如果我的理解是正确的,请看一下this post:这家伙毫不掩饰它是一个黑客,尽管包括
mysql_priv.h无论如何都会放弃实现的黑客性质。看起来他的代码可以从 UDF 的主体中访问内存中的 mysql 表;相同的路径可能会引导您找到允许您访问索引的解决方案。 -
@jmilloy MySQL 访问表和 UDF 使用 MySQL 的 private 标头访问表之间的区别在于 UDF 与 MySQL 的发布周期不同:如果设计师MySQL 决定明天更改他们的标题和内部结构,他们也会更改其余代码以匹配标题中的更改,并且没问题;相比之下,UDF 就会崩溃。更糟糕的是,他们可以在不让任何人知道的情况下对其语义进行重大更改。对他们来说,这是一场公平的比赛,因为标题是私有的。对于其他依赖私有标头的人来说,这是一个很大的风险。