【发布时间】:2021-05-04 05:21:31
【问题描述】:
环境:
mariadb-java-client-2.7.0
数据库:MariaDB 10.5.7
ojdbc8 - Oracle 11.2.0.3.0 JDBC 4.0
数据库:Oracle 数据库 11g
休眠 4.3.8
代码:
Session session = sessionFactory.openSession();
Criteria fetchCriteria = session.createCriteria("Student");
Disjunction disjunction = Restrictions.disjunction();
for (int i = 1; i <= 10000; i++) {
Conjunction conjunction = Restrictions.conjunction();
conjunction.add(Restrictions.eq("RollNumber", i+""));
disjunction.add(conjunction);
}
fetchCriteria.add(disjunction);
long start1 = System.currentTimeMillis();
List resultList = fetchCriteria.setFirstResult(0).setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP).list();
long end1 = System.currentTimeMillis();
System.out.println("Time took :"+(end1-start1) +"ms");
问题
- 如果我使用 Hibernate 4.3.8 + Oracle 8 运行上述代码,则所需时间不到 5000 毫秒。
- 如果我使用 Hibernate 4.3.8 +mariadb-java-client-2.7.0 运行上述代码,则需要超过 40,000 毫秒。
额外配置: 我在 hibernate.cfg.xml 中将 hibernate.jdbc.fetch_size 设置为 100 以及 jdbc URL、用户名和密码。
调查结果:
- 在这两种情况下生成的查询是相同的,如果我执行那些 使用 SQL 客户端查询 ORACLE 需要 10-11 秒,MariaDB 需要 41-42 秒。
- 如果我使用 JDBC 调用,则由两个数据库生成的查询 程序(对于 ORACLE 和 MariaDB)大约需要 600 毫秒
注意:两个表(Oracle 和 MariaDB)都有 15,000 条记录。
谁能帮助我为什么 MariaDB 需要时间? 或者需要一些额外的设置来提高 MariaDB 的性能。 我试过https://mariadb.com/kb/en/about-mariadb-connector-j/中提到的defaultFetchSize,但没有运气。
数据库生成的 SQL 查询:
select this_.rollNo as RollNo1_0_0_, this_.VersionID as Version2_0_0_,
this_.Name as Name3_0_0_, this_.dept as dept4_0_0_,
this_.favSubj as favSubj5_0_0_,
this_.ID as ID33_0_0_
from Student this_
where ((this_.ID='1')
or (this_.ID='2')
or (this_.ID='3')
or ....
or (this_.ID='10000')
MariaDB DDL
CREATE TABLE `student` (
`RollNo` bigint(20) NOT NULL ,
`VersionID` bigint(20) NOT NULL,
`Name` varchar(100) COLLATE ucs2_bin DEFAULT NULL,
`dept` varchar(100) COLLATE ucs2_bin DEFAULT NULL,
`favSubj` varchar(100) COLLATE ucs2_bin DEFAULT NULL,
`ID` varchar(100) COLLATE ucs2_bin DEFAULT NULL,
PRIMARY KEY (`RollNo`),
UNIQUE KEY `UK_student` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=20258138 DEFAULT CHARSET=ucs2 COLLATE=ucs2_bin
Oracle DDL
CREATE TABLE student (
RollNo NUMBER(19,0),
VersionID NUMBER(19,0) NOT NULL ENABLE,
Name VARCHAR2(100),
dept VARCHAR2(100),
favSubj VARCHAR2(100),
ID VARCHAR2(100),
PRIMARY KEY ("RollNo"),
CONSTRAINT "UK_student" UNIQUE ("ID")
)
MariaDB 解释选择查询输出
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | this_ | range | UK_Student | UK_Student | 203 | NULL | 10000 | Using index condition |
【问题讨论】:
-
请提供生成的SQL和表定义。
-
请咨询您的 DBA。您可能缺少 Oracle 中的 MariaDB 索引。
-
@RickJames 添加表定义并生成 SQL。
-
@ChristianBeikov 索引正确。
-
我猜 Oracle 在优化/执行这个查询方面比 MariaDB 更好。使用
EXPLAIN查看 MariaDB 生成的查询计划并将其与 Oracle 的查询计划进行比较。它还取决于运行数据库的机器。
标签: java oracle hibernate mariadb mariadb-connect-engine