当前位置: 首页 > 面试题库 >

如何通过“分组依据”和“位置”加快“选择计数(*)”?

吕奇
2023-03-14
问题内容

如何加快select count(*)group by
它太慢并且经常使用。
我用很大的麻烦select count(*),并group by具有300多万行的表。

select object_title,count(*) as hot_num   
from  relations 
where relation_title="XXXX"   
group by object_title

Relation_titleobject_title 为varchar。 其中Relation_title =’XXXX’
,返回超过1,000,000行,导致 object_title 上的索引 无法正常工作。


问题答案:

为了提高难度,我尝试了以下几种方法:

(更轻松) - 确保您具有正确的覆盖指数

CREATE INDEX ix_temp ON relations (relation_title, object_title);

在给定现有架构的情况下,这应该使性能最大化,因为(除非您的mySQL优化器版本真的很笨!)它将最小化满足查询所需的I /
O数量(与索引相反的情况不同,即整个索引必须进行扫描),它会覆盖查询,因此您无需触摸聚簇索引。

(稍微难一点)-确保您的varchar字段尽可能小

MySQL上使用varchar索引的性能挑战之一是,在处理查询时,字段的完整声明大小将被拉入RAM。因此,如果您具有varchar(256),但仅使用4个字符,则在处理查询时,您仍然需要支付256字节的RAM使用量。哎哟!
因此,如果您可以轻松缩小varchar限制,则可以加快查询速度。

(更难)-标准化

您有30%的具有单个字符串值的行显然可以正常化到另一个表中,因此您不会将字符串重复数百万次。考虑将其标准化为三个表,并使用整数ID将它们联接。

在某些情况下,您可以在幕后进行归一化,并使用与当前表名称匹配的视图隐藏归一化…然后,您只需要使INSERT / UPDATE /
DELETE查询知道该归一化,但可以不理会SELECTs 。

(最困难)-散列字符串列并为哈希索引

如果规范化意味着更改太多代码,但是您可以稍微更改架构,则可能要考虑为字符串列创建128位哈希(使用MD5函数)。在这种情况下(与规范化不同),您不必更改所有查询,而只需更改INSERT和某些SELECT。无论如何,您将需要对字符串字段进行哈希处理,然后在哈希表上创建索引,例如

CREATE INDEX ix_temp ON relations (relation_title_hash, object_title_hash);

请注意,您将需要使用SELECT来确保通过哈希索引进行计算,而不要拉入聚集索引(需要解析object_title的实际文本值才能满足查询)。

另外,如果relationship_title具有较小的varchar大小,但对象标题具有较大的大小,则可能仅散列object_title并在上创建索引(relation_title, object_title_hash)

请注意,仅当这些字段中的一个或两个相对于哈希值的大小很长时,此解决方案才有用。

还要注意,由于小写字符串的哈希值与大写字符串的哈希值不同,因此哈希值会引起有趣的区分大小写/排序规则的影响。因此,您需要确保对字符串进行规范化之后再对它们进行哈希处理-
换句话说,如果您在不区分大小写的数据库中,则仅对小写字母进行哈希处理。您还可能需要从头或尾开始修剪空格,具体取决于数据库处理前导/尾随空格的方式。



 类似资料:
  • 问题内容: 在Symfony2和Doctrine中,我想执行一个返回计数和分组依据的查询。 这是我尝试过的。这是我要运行的SQL: 与我的实体: 这是我的PartieRepository 这是我得到的错误: 问题答案: 您可能要使用本机查询 只需根据需要添加任何具有/ where子句。 以下是我的结果: 第一个数组中缺少的原因是null 。 编辑 OP产生了意外的结果,因此这是一些故障排除步骤:

  • 问题内容: 我有这样的桌子 我想写一个选择查询,这样我就可以得到这样的结果 在这里,我需要按ID和数量总和进行分组,并用相同的ID和Differentnet名称连接字符串名称 问题答案: 这将与sql-server 2008一起使用

  • 我正在使用SQLServer2008,我想知道我是否可以在一个select语句中完成查询,而不需要子查询。 如果记录中的某个字段在最近10个创建的记录中为true,我想将变量设置为true,如果该字段在最近10个记录中为true,则变量为true,如果为false,则变量为false,如果记录总数小于10,则变量也为false。 我的问题是,要获取最新创建的10条记录,我需要通过降序对用户进行排序

  • 问题内容: 我有一个看起来像这样的模型: 我想要为每个类别选择项目的计数(只是计数),因此在SQL中,它会像这样简单: 有没有相当于做这种“ Django方式”?还是纯SQL是唯一的选择?我熟悉Django中的count()方法,但是我看不出group by如何适合那里。 问题答案: 正如我刚刚发现的,这里是如何使用Django 1.1聚合API进行此操作:

  • 问题内容: 我正在尝试转换此查询(已经可以使用) 对于Linq to SQL,但我不知道自己在做什么错。看我的尝试 我只需要对建筑物进行分组并计算每个建筑物有多少用户。 问题答案: 只需使用以下方法:

  • 问题内容: 我有如下的SQL: 并得到结果: 我想总结每个部门的学生人数,如下所示: 我该如何编写sql? 问题答案: 尽管您似乎并未显示所有表格,但我只能假设还有每位学生的实际入学表格 如果您想要与每个学生相关联的每个部门的总数(这没有意义),则可能必须这样做… 我对“姓名”列的解释是学生的姓名,而不是班级实际讲师的姓名,因此,我进行子选择/加入。否则,就像其他人一样,只需要使用COUNT(*)