【发布时间】:2022-01-05 19:14:30
【问题描述】:
我在 Azure SQL 数据库中创建了一个简单的表
以下 Python 脚本仅需 3ms 即可从 Azure SQL Server 执行选择查询
import os
import sys
import logging, logging.handlers
import getopt
import pyodbc
# set up logging
logging.getLogger().setLevel(logging.INFO)
console = logging.StreamHandler()
console.setFormatter(logging.Formatter('%(asctime)s %(name)-12s %(levelname)s %(message)s'))
console.setLevel(logging.INFO)
logging.getLogger().addHandler(console)
logger = logging.getLogger("purgeStaleTags")
server = 'sqlsrv-01.database.windows.net'
database = 'db'
username = 'user'
password = 'p@$$word'
driver= '{ODBC Driver 17 for SQL Server}'
logger.info("Before Connect")
connection=pyodbc.connect('DRIVER='+driver+';SERVER=tcp:'+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password+';Encrypt=yes;TrustServerCertificate=no;')
logger.info("Before Cursor")
cursor=connection.cursor()
logger.info("After Cursor")
cursor.execute("SELECT item_id FROM offer_table WHERE offer_id = 23583");
records=cursor.fetchall()
logger.info(len(records))
logger.info("After Query")
日志
>>> logger.info("Before Connect")
2022-01-05 19:00:30,638 purgeStaleTags INFO Before Connect
>>> connection=pyodbc.connect('DRIVER='+driver+';SERVER=tcp:'+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password+';Encrypt=yes;TrustServerCertificate=no;')
>>> logger.info("Before Cursor")
2022-01-05 19:00:30,871 purgeStaleTags INFO Before Cursor
>>> cursor=connection.cursor()
>>> logger.info("After Cursor")
2022-01-05 19:00:30,871 purgeStaleTags INFO After Cursor
>>> cursor.execute("SELECT item_id FROM offer_table WHERE offer_id = 23583");
<pyodbc.Cursor object at 0x7f05f45280b0>
>>> records=cursor.fetchall()
>>> logger.info(len(records))
2022-01-05 19:00:30,884 purgeStaleTags INFO 30
>>> logger.info("After Query")
2022-01-05 19:00:30,884 purgeStaleTags INFO After Query
但是下面的 spring 应用程序需要 80ms 来执行来自 Azure SQL Server 的选择查询?
Java 应用程序:
public class JDBCSample {
public static void main(String[] args) {
...
try {
Connection conn = dataSource().getConnection();
conn.setAutoCommit(false);
Statement statement = conn.createStatement();
ResultSet rs ;
try {
LocalDateTime executionStartTime = LocalDateTime.now();
System.out.println("Select Query Execution Started: " + dtf.format(executionStartTime));
rs = statement.executeQuery("SELECT item_id FROM offer_table WHERE offer_id = 23583");
executionEndTime = LocalDateTime.now();
System.out.println("Select Query Execution Completed: " + dtf.format(executionEndTime));
}
catch (SQLException ex)
{
System.out.println("Error message: " + ex.getMessage());
return; // Exit if there was an error
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Bean(destroyMethod = "close")
public static DataSource dataSource(){
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
hikariConfig.setJdbcUrl("jdbc:sqlserver://....;encrypt=true;trustServerCertificate=false;");
hikariConfig.setUsername("...");
hikariConfig.setPassword("...");
hikariConfig.setMaximumPoolSize(1);
hikariConfig.setConnectionTestQuery("SELECT 1");
hikariConfig.setPoolName("springHikariCP");
HikariDataSource dataSource = new HikariDataSource(hikariConfig);
return dataSource;
}
}
日志
INFO : 01.06.2022:0032 (31.802) [[]main] HikariDataSource: springHikariCP - Starting...
INFO : 01.06.2022:0032 (33.314) [[]main] HikariDataSource: springHikariCP - Start completed.
Execution Started: 2022/01/06 00:32:33.436
INFO : 01.06.2022:0032 (33.437) [[]main] HikariDataSource: springHikariCP - Starting...
INFO : 01.06.2022:0032 (33.927) [[]main] HikariDataSource: springHikariCP - Start completed.
Select Query Execution Started: 2022/01/06 00:32:34.043
Select Query Execution Completed: 2022/01/06 00:32:34.122
延迟在哪里?我该如何解决这个问题,以使 Spring 应用程序花费的时间不会超过 2 毫秒。
【问题讨论】:
-
只是检查。您是否尝试过对多个查询进行计时? Azure 可能会比 Python 进行更多的设置和初始化,但后续查询会更快。
-
是的,我尝试了 5 个选择查询。 Python 需要 12ms 到 22ms,spring 需要 350ms
-
尝试通过
DriverManagerJDBC API 连接而不是通过HikakiCPDataSource。也许是 HikariCP 的延迟加载什么的(不知道)。对 Java 程序进行微基准测试很难:通常建议在测量之前重复运行代码几分钟,以便 JVM 有机会将 Java 字节码编译为本机代码。 -
作为健全性检查 - 您是否尝试过针对本地 SQL 服务器进行基准测试 - 您是否发现运行时有任何明显差异?
-
对python使用这些计时方法并检查代码中的时间并检查您是否没有弄错计时选项:
start_time=time.time()end_time=time.time()print('time: ' +str(end_time-start_time))
标签: python spring azure-sql-database hikaricp azure-sql-server