何时进入'IN,何时不进入?

问题描述 投票:1回答:4

假定您正在为零售商店链编写应用程序。因此,您将设计对象模型,以便将“商店”定义为核心业务对象和许多支持对象。假设“商店”如下所示:

class Store implements Validatable{
int storeNo;
int storeName;
... etc.... 
}

因此,您的客户告诉您,您必须将Excel表格中的商店计划导入到应用程序中,并且您必须在'em上运行一系列验证。例如,'StoreIsInSameCountry';'StoreIsValid'...等。因此,您将设计一个Rule接口来检查所有业务条件。像这样:

interface Rule T extends Validatable> {
public Error check(T value) throws Exception;
}

现在,问题来了。我正在从此Excel工作表中上传2000家商店。因此,我最终会多次运行为商店定义的每个规则。如果我要对数据库有4条规则= 8000个查询,即对连接池的匹配数为16000次。对于仅需检查商店是否存在的简单检查,查询将是:

 SELECT STORE_ATTRIB1, STORE_ATTRIB2... from STORE where STORE_ID = ?

这样,我将获得我的'Store'对象。如果我没有从数据库中得到任何东西,那么该存储就不存在。因此,对于这样一个简单的检查,我将不得不对2000个商店的数据库进行2000次访问。

或者,我可以做:

SELECT STORE_ATTRIB1, STORE_ATTRIB2... from STORE where STORE_ID in (1,2,3..... ) 

此查询实际上比其上面的查询返回2000倍的返回速度快得多。但是,只能在单个商店中运行规则的设计并不合适。

我知道不建议使用IN方法。那么,您认为我应该怎么做?我应该继续在这里使用IN吗,因为在这种情况下它可以提供更好的性能?还是应该更改设计?

如果您穿着我的鞋子,您会怎么做?最佳做法是什么?

java database performance jdbc
4个回答
2
投票

这样,我将从数据库中获取我的'Store'对象。如果我没有从数据库中得到任何东西,那么该存储就不存在。因此,对于这种简单的检查,我将不得不对2000个商店的数据库进行2000次访问。

这是您不应要做的。

创建一个临时表,用您的值填充表,然后JOIN将此表填充,如下所示:

SELECT  STORE_ATTRIB1, STORE_ATTRIB2...
FROM    temptable tt
JOIN    STORE s
ON      s.STORE_ID = t.id

或此:

SELECT  STORE_ATTRIB1, STORE_ATTRIB2...
FROM    STORE s
WHERE   s.STORE_ID IN
        (
        SELECT  id
        FROM    temptable tt
        )

我知道不建议使用IN方法。那么,您认为我应该怎么做?我应该继续在这里使用IN吗,因为在这种情况下它可以提供更好的性能?还是应该更改设计?

[IN筛选出重复项。

如果要为列表中的每个重复值选择每个符合条件的行,请使用JOIN

IN绝不是“不建议使用的方法”。

实际上,有一段时间有些数据库不有效地支持IN查询,这就是为什么民间智慧仍然建议不要使用它。

但是如果您的store_id被正确索引(很可能是索引,如果它看起来像是PRIMARY KEY),那么所有主要数据库的现代版本(即OracleSQL Server,[C0 ]和MySQL)将使用有效的计划来执行此查询。

请参阅我的博客中的本文,以获取PostgreSQL中的性能详细信息:

  • SQL Server

注意,在正确设计的数据库中,验证规则也是基于集合的。

I。 e。您可以将验证规则作为对IN vs. JOIN vs. EXISTS的查询来实现。

但是,要支持旧规则,您可以从临时行逐列选择行中的值,应用规则,并删除未通过验证的值。


1
投票
IN

甚至

JOIN

将在一个查询中告诉您所有活动商店。现在,您可以对已知存在的商店进行其他测试,并且您自己保存到数据库的匹配数为1,999。

如果您具有相对无争议的数据库访问权限,并且没有时间限制整个过程需要花费多长时间,那么您就不必担心一遍又一遍地访问连接池。毕竟,这就是它的目的!


0
投票

我认为这更多的是一个业务问题,其参数为客户端多长时间运行一次导入,您需要花费多长时间来实施任一解决方案以及每小时花费多少时间。

如果它偶尔运行一次,我认为有些性能下降是可以接受的,特别是如果您可以使用干净的代码快速完成工作。


0
投票

...规则只能在单个商店中运行。

管理业务规则和性能是一项艰巨的任务,因此有一个库(EXISTS)可以做到这一点。您定义规则,然后执行大量命令,然后在单个查询中(通过使用临时表而不是“ IN”)从数据库中提取库,无论规则需要什么,然后将其传递给规则。temptable中有一个验证程序的示例。

© www.soinside.com 2019 - 2024. All rights reserved.