[英]MyBatis and SQL, best performance query
我知道这是执行查询的最佳方法,将以下内容链接起来。 我需要优化性能,并避免在DB(postgresql)中进行无用的操作。
用户将输入一系列过滤器,这些过滤器是两个值(“ id_meta”和“ value”),这将减少我从“ meta”表中提取的行数。 这些字段不是PK。
这是一个示例 ,该表具有更多列,但是那些是感兴趣的。
| id_meta | value | id_ud |
| ------- |:----------:| -----:|
| 1 | pippo | 45 |
| 2 | 10 | 45 |
| 3 | 21/05/2010 | 45 |
| 1 | pluto | 35 |
| 2 | 14 | 35 |
| 3 | 22/05/2010 | 35 |
依此类推...如果用户输入了(1:pippo)和(2:14)对,则查询将返回0行,因为第一个过滤器(45)返回的id_ud没有(2:14) 。
它不能同时为同一个id_meta赋予不同的值,例如(1:pippo)AND(1:pluto)之类的事情是不可能的
因此,基本上每两个过滤器都是一个嵌套子查询,这些子查询减少了第一个结果集的数量。 如果用户提供3个过滤条件,我将进行3个子查询
select id_ud
from meta
where id_meta = 12
and value = '45'
and id_ud in (select id_ud
from meta
where id_meta = 10
and value = 1000
and id_ud in (select id_ud
from meta
where id_meta = 6
and value = 'll'
)
)
我需要计算返回的行数,还有另一个条件
select count(id_ud)
from meta
where id_ud in (select ID_UD
from documento
where stato = 'ACHIVIATO'
and id_cat_doc = 2)
and value= '2010'
and id_meta = 12 and id_ud in (select id_ud
from meta
where id_meta = 10
and value = 1000
and id_ud in (select id_ud
from meta
where id_meta = 6
and value = 'll'
)
);
因此,基本上,我必须使用MyBatis动态创建一个嵌套子查询并计算返回的值,如上面的最后一个示例。 有没有一种方法可以避免使用ANY,ALL,UNION或其他SQL构造的所有子查询,pherap?
谢谢,请随时添加更多详细信息,我不确定我是否清楚解释了我的问题...
我正在尝试使用mybatis构建此查询
select
count (id_ud)
from
documento
where
stato = 'ARCHIVIATO'
and id_categoria_documentale = #{param2, jdbcType=BIGINT}
<foreach item="value" index="key" collection="param1.entrySet()" open=" and id_ud in ("
separator=" and id_ud in (" close="))">
select
id_ud
from
meta
where
id_meta = #{key, jdbcType=INTEGER}
and value = #{value, jdbcType=VARCHAR}
</foreach>
其中param1是包含所有用户过滤器的地图对象。 我在添加正确的结束数时遇到问题)...有任何想法吗?
尝试这个
select count(id_ud)
from meta mt1
join (select ID_UD from documento where stato = 'ACHIVIATO' and id_cat_doc = 2) doc on (doc.ID_UD = mt1.id_ud)
join (select id_ud from meta where id_meta = 10 and value = 1000 ) mt2 on (mt2.id_ud = mt1.id_ud)
join (select id_ud from meta where id_meta = 6 and value = 'll' ) mt3 on (mt3.id_ud = mt2.id_ud)
where value= '2010' and id_meta = 12
这应该更快。
编辑:另一种方式:
select count(id_ud)
from meta mt1
join (select ID_UD from documento where stato = 'ACHIVIATO' and id_cat_doc = 2) doc on (doc.ID_UD = mt1.id_ud)
where (1=1) --always true
or (value= '2010' and id_meta = 12) and (id_meta = 6 and value = 'll') and (id_meta = 10 and value = 1000) --user conditions
您可以在脚本/程序中建立动态查询
您的查询或多或少与标签搜索,全文搜索或约会搜索相同。 因此,使用针对此类情况已经优化的搜索方法是有意义的。
幸运的是,postgres支持的全文似乎很合适。
我建议将整个“元”表合并为表“ documento”中的一列,以表示标记。 我们将此列命名为“标签”。
对于id_ud = 45,它将包含“ 1 = pippo 2 = 14 3 = 21/05/2010”
为了说服全文搜索引擎将标记视为“单词”,您可能必须使用除“:”之外的其他内容,禁用词法分析和其他奇特的选项等。
这应该相当快。
由于您有日期,因此另一个选择是为这些日期提供表“ documento”中的真实列。 例如,如果您有发布日期,为什么不将其放在带有索引的列中? 这也将允许范围(日期之间...和...)搜索。 关系数据库喜欢将数据放在列中……这是标准的,也是最高效的……像您一样的“元”表总是很麻烦。
可以使用位图索引扫描来组合多个独立的列索引,这非常快。
另一种方法是将标签放在“ documento”表中,但在hstore中。 这样,一条记录的所有标记都在同一行上,并且可以在hstore中的键上使用部分索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.