假定您正在为零售商店链编写应用程序。因此,您将设计对象模型,以便将“商店”定义为核心业务对象和许多支持对象。假设“商店”如下所示:
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吗,因为在这种情况下它可以提供更好的性能?还是应该更改设计?
如果您穿着我的鞋子,您会怎么做?最佳做法是什么?
这样,我将从数据库中获取我的'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
),那么所有主要数据库的现代版本(即Oracle
,SQL Server
,[C0 ]和MySQL
)将使用有效的计划来执行此查询。
请参阅我的博客中的本文,以获取PostgreSQL
中的性能详细信息:
SQL Server
注意,在正确设计的数据库中,验证规则也是基于集合的。
I。 e。您可以将验证规则作为对IN
vs. JOIN
vs. EXISTS
的查询来实现。
但是,要支持旧规则,您可以从临时行逐列选择行中的值,应用规则,并删除未通过验证的值。
IN
甚至
JOIN
将在一个查询中告诉您所有活动商店。现在,您可以对已知存在的商店进行其他测试,并且您自己保存到数据库的匹配数为1,999。
如果您具有相对无争议的数据库访问权限,并且没有时间限制整个过程需要花费多长时间,那么您就不必担心一遍又一遍地访问连接池。毕竟,这就是它的目的!
我认为这更多的是一个业务问题,其参数为客户端多长时间运行一次导入,您需要花费多长时间来实施任一解决方案以及每小时花费多少时间。
如果它偶尔运行一次,我认为有些性能下降是可以接受的,特别是如果您可以使用干净的代码快速完成工作。
...规则只能在单个商店中运行。
管理业务规则和性能是一项艰巨的任务,因此有一个库(EXISTS
)可以做到这一点。您定义规则,然后执行大量命令,然后在单个查询中(通过使用临时表而不是“ IN”)从数据库中提取库,无论规则需要什么,然后将其传递给规则。temptable
中有一个验证程序的示例。