我有一组数据,如下所示:
id name c1 c2 c3 c4 ... c50
-----------------------------------------------
1 string1 0.1 0.32 0.54 -1.2 ... 2.3
2 string2 0.12 0.12 -0.34 2.45 ... 1.3
...
(millions of records)
所以我有一个id列,一个字符串列,然后是50个浮点列。
在此数据上只运行一种类型的查询,在传统的SQL SELECT语句中如下所示:
SELECT name FROM table WHERE ((a1-c1)+(a2-c2)+(a3-c3)+...+(a50-c50)) > 1;
其中a1,a2,a3,etc
是在发送查询之前生成的值(不包含在数据表中)。
我的问题是:是否有人建议哪种类型的数据库最快处理此类查询。我使用SQL server
(主要是慢速),所以我正在寻找其他意见。
是否有办法针对此类查询优化SQL Server?我也对MonetDB
等列存储数据库感到好奇。或者可能是文档存储数据库,例如MongoDB
。有没有人有任何建议?
非常感谢, 布雷特
答案 0 :(得分:10)
您可以继续使用SQL Server并使用persisted computed column来计算所有值的总和并将其编入索引。
ALTER TABLE tablename ADD SumOfAllColumns AS (c1 + c2 + ... + c50) PERSISTED
然后您可以将查询重新排列为:
SELECT name FROM tablename WHERE SumOfAllColumns < a1+a2+a3+...+a50 - 1
此查询将能够使用计算列上的索引,并且应该快速找到相关的行。
答案 1 :(得分:2)
坚持使用SQL Server:
如果您始终在查询中包含相同的计算(相同的字段+或 - 相同的其他字段等),您可以创建computed columns with persisted values.
目前,您的查询速度很慢,因为引擎正在为每一行运行复杂的数学运算。
如果添加包含结果的列,则数学运算完成一次,然后运行查询会快得多。
答案 2 :(得分:0)
内存数据库最好。看看http://hsqldb.org/
取决于您拥有的数百万行...
答案 3 :(得分:0)
您的查询条件可以重写为:
(a1 + a2 + a3 + ... + a50) > 1 + (c1 + c2 + c3 + ... + c50)
您可以在数据库端预先计算c = 1 + c1 + ... + c50
,在客户端预先计算a = a1 + ... + a50
。然后查询减少到... WHERE @a > c
。这开启了使用索引的机会。
但是,在大多数数据库(包括SQL Server)中,浮点数不能很好地编制索引。如果我们可以对数据做出一些假设,我们或许可以解决这个问题。例如,如果数字仅存储为两个精度数字,如示例所示,那么我们可以将所有数字乘以100以获得整数。然后,索引将很好地工作。合理地说,这是......它取决于满足条件的行数。 “数百万行”的一半仍然是很多行。
即使值具有真正可变的精度,因此两个数字不够准确,创建整数索引以减少需要检查的行可能仍然有意义。查询可以检查近似值(命中索引)和确切值(以获得精确结果)。如果这样做,请确保原始值在正确的方向上舍入,以避免丢失精确的结果。