MYSQL获取当前时间和开始时间、结束时间对应的状态

本文通过实例解析了如何使用Mybatis动态SQL查询bd_job表中的任务状态,包括作业未开始、进行中和截止情况,并结合实际业务逻辑进行了代码片段展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键代码

mybatis

<select id="selectBdJobStatusByNow" parameterType="Long" resultType="java.util.HashMap">
    select NOW()>start_time as startStatus,NOW()>end_time as endStatus
    from bd_job
    where  id = #{jobId};

mysql语句

select NOW()>start_time as startStatus,NOW()>end_time as endStatus from bd_job where  id = 00000000001;

执行结果

在这里插入图片描述

在这里插入图片描述
根据sql语句:

 HashMap<String,Integer> jobStatus = bdJobContentAnswerService.selectBdJobStatusByNow(jobId);
        if(jobStatus.get("startStatus").equals(0)){ //作业未开始
            return AjaxResult.success("作业还未开始");
        }else if(jobStatus.get("endStatus").equals(0)) { //作业进行中

        }else if(jobStatus.get("endStatus").equals(1)){ //作业已截止

        }else {
            return AjaxResult.error("接口请求错误!");
        }

注:说的比较乱,希望意思能理解

<think>嗯,用户之前让我帮忙写一个可以并行执行20个SQL的shell脚本,现在他们又想要基于之前的脚本结果来统计每条SQL的执行时间。好的,我需要仔细分析他们的需求,看看如何在现有的脚本基础上添加时间统计的功能。 首先,回顾之前的脚本,用户已经使用了timeout命令来限制每个SQL的执行时间,并且将输出错误信息重定向到日志文件中。现在需要统计每条SQL的执行时间,那么就需要在运行每个SQL的时候记录开始结束时间,然后计算时间差。 可能的实现方法是在execute_sql函数里添加时间记录的代码。比如,在运行mysql命令之前获取当前时间戳,命令执行后再获取一次,两者相减得到执行时间。这可以通过date命令来实现,比如date +%s获取秒数,或者date +%s%3N获取毫秒精度的时间戳。 然后需要考虑如何将执行时间记录到日志中。用户可能希望每条SQL的执行时间不仅显示在控制台,还要保存到对应的日志文件里,或者单独汇总到一个总的时间统计文件中。需要根据用户的需求来决定。 另外,原来的日志文件已经保存了mysql命令的输出错误信息,现在添加的时间信息可能需要放在日志文件的开头或者结尾,或者单独记录到另一个文件中。但用户可能更希望时间信息整合到现有的日志中,方便查看。 接下来是并发处理的问题。原来的脚本使用了后台进程作业控制来限制并发数量。添加时间统计是否会影响并发机制?应该不会,因为时间记录是在每个子进程中独立进行的,不会互相干扰。但需要注意,如果在多个进程中同时写入同一个汇总文件,可能会导致内容交错,需要使用文件锁或者单独的文件来避免。 可能的解决方案是在每个execute_sql函数中,计算执行时间后,将该时间SQL文件名一起输出到一个临时文件,然后在所有任务完成后,汇总这些临时文件生成总的执行时间报告。或者,直接在日志文件中记录时间,然后在脚本最后解析所有日志文件提取时间信息。 另外,用户可能需要不同的时间格式,比如秒、毫秒,或者更易读的时分秒格式。需要询问用户是否需要特定的时间格式,但根据常规需求,使用秒或毫秒可能更常见。 在脚本中,可以通过在execute_sql函数内部添加时间记录。例如: start_time=$(date +%s) 执行mysql命令 end_time=$(date +%s) duration=$((end_time - start_time)) 然后将duration记录到日志中,或者输出到控制台。如果用户希望每个日志文件包含该SQL的执行时间,可以在重定向时将时间信息追加进去。例如: echo "开始时间: $(date)" >> "$log_file" mysql ... >> "$log_file" 2>&1 echo "执行时间: $duration 秒" >> "$log_file" 不过,原来的脚本中使用的是将mysql的输出直接重定向到日志文件,所以可能需要调整结构,先记录开始时间,执行命令,然后计算持续时间并追加到日志文件中。 另外,考虑到timeout命令的使用,如果SQL执行超时,实际执行的时间可能等于TIMEOUT_SEC设置的值,这时候需要检查是否超时,并在日志中注明超时情况。 可能的修改步骤: 1. 在execute_sql函数中,记录开始时间。 2. 执行mysql命令,并捕获退出状态。 3. 记录结束时间,计算持续时间。 4. 根据退出状态判断是否超时,并将时间信息写入日志文件或汇总文件。 5. 在脚本最后,汇总所有SQL的执行时间,输出到控制台或生成报告。 此外,用户可能需要将执行时间汇总到一个独立的文件中,方便后续分析。比如,在每个SQL执行完成后,将文件名、开始时间结束时间、持续时间写入一个CSV文件。 同时,需要考虑并发写入同一文件的问题,可以使用flock命令进行文件锁定,或者让每个进程写入独立的临时文件,最后合并。 不过,这样可能会增加脚本的复杂度。可能更简单的方式是在每个进程内部将时间信息追加到自己的日志文件中,然后在所有任务完成后,使用awk或其他工具解析所有日志文件,提取时间信息生成报告。 例如,每个日志文件中包含类似的行: [时间统计] 开始时间: 1620000000, 结束时间: 1620000005, 执行时间: 5秒 然后在脚本的最后,遍历所有日志文件,提取这些行进行汇总。 或者,在execute_sql函数中,将时间信息输出到控制台,并在脚本的最后统一处理输出,但并发执行时,输出可能会交错,难以捕获。因此,更好的方法是将时间信息写入每个SQL的日志文件中,最后统一分析。 综上所述,可能的修改如下: 在execute_sql函数中,添加时间记录: execute_sql() { local sql_file=$1 local log_file="$LOG_DIR/$(basename "$sql_file" .sql).log" local start_time=$(date +%s) echo "开始时间: $(date -d @$start_time)" > "$log_file" timeout $TIMEOUT_SEC mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$sql_file" >> "$log_file" 2>&1 local exit_status=$? local end_time=$(date +%s) local duration=$((end_time - start_time)) echo "结束时间: $(date -d @$end_time)" >> "$log_file" echo "执行时间: $duration 秒" >> "$log_file" if [ $exit_status -eq 0 ]; then echo "[SUCCESS] $sql_file 执行时间: $duration 秒" ((SUCCESS++)) else if [ $exit_status -eq 124 ]; then echo "[TIMEOUT] $sql_file 超时,设置时间: $TIMEOUT_SEC 秒" >> "$log_file" echo "[FAILED] $sql_file (超时,详见 $log_file)" else echo "[FAILED] $sql_file (错误码: $exit_status, 详见 $log_file)" fi ((FAILED++)) fi } 这样,每个日志文件会记录开始时间结束时间执行时间,同时在控制台输出也会显示执行时间。此外,还可以在脚本最后生成一个汇总报告,统计所有SQL的执行时间。 然后,可以添加一个函数来解析日志文件,生成汇总报告: generate_report() { echo -e "\n===== SQL执行时间统计 =====" echo "SQL文件 | 执行时间(秒) | 状态" for log in "$LOG_DIR"/*.log; do local sql_file=$(basename "$log" .log).sql local duration=$(grep "执行时间: " "$log" | awk '{print $2}') local status=$(grep -o "\[SUCCESS\]\|\[FAILED\]\|\[TIMEOUT\]" "$log" | tail -n1) echo "$sql_file | $duration | $status" done } 然后在脚本末尾调用这个函数。 不过,需要注意的是,在并发执行时,多个进程同时写入日志文件可能会导致内容交错,但在这里每个进程写入自己的日志文件,因此不会冲突。因此,上述方法应该是可行的。 另外,如果用户需要更详细的报告,比如总执行时间、平均时间、最长最短时间等,可以在汇总时进行处理。但可能超出当前需求范围,需要用户确认。 最后,测试修改后的脚本,确保时间统计正确,特别是超时情况的处理是否正确。例如,当SQL执行超过TIMEOUT_SEC时,timeout会终止进程,返回状态124,此时记录的持续时间应该等于TIMEOUT_SEC还是实际执行的时间?实际上,timeout会在指定的时间后终止命令,所以实际执行时间应该接近TIMEOUT_SEC,但可能略有误差。因此,在日志中记录真实的开始结束时间,计算出的duration会更准确。 综上,修改后的脚本应满足用户的需求,统计每条SQL的执行时间,并在日志控制台中显示相关信息。</think>以下是在原脚本基础上**增加执行时间统计**的改进版本,包含每条SQL的耗时记录与汇总报告: --- ### **更新后的脚本 `parallel_sql_runner_with_time.sh`** ```bash #!/bin/bash # 配置信息(同上,略) DB_HOST="localhost" DB_PORT="3306" DB_USER="root" DB_PASS="your_password" DB_NAME="test_db" SQL_DIR="./sql_scripts" SQL_FILES=("$SQL_DIR"/*.sql) MAX_PARALLEL=20 LOG_DIR="./logs" TIMEOUT_SEC=300 mkdir -p "$LOG_DIR" # 新增:时间统计文件 TIME_REPORT="$LOG_DIR/time_report.csv" echo "sql_file,start_time,end_time,duration_sec,status" > "$TIME_REPORT" TOTAL=0 SUCCESS=0 FAILED=0 execute_sql() { local sql_file=$1 local log_file="$LOG_DIR/$(basename "$sql_file" .sql).log" # 记录开始时间(Unix时间戳) local start_time=$(date +%s) # 执行SQL(新增时间统计逻辑) timeout $TIMEOUT_SEC mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$sql_file" > "$log_file" 2>&1 local exit_code=$? # 计算持续时间 local end_time=$(date +%s) local duration=$((end_time - start_time)) # 记录结果到CSV local status if [ $exit_code -eq 0 ]; then status="success" ((SUCCESS++)) elif [ $exit_code -eq 124 ]; then status="timeout" ((FAILED++)) else status="failed" ((FAILED++)) fi # 使用flock防止并发写入冲突 flock -x 200 echo "$(basename "$sql_file"),$start_time,$end_time,$duration,$status" >> "$TIME_REPORT" echo "[$status] $sql_file (耗时: ${duration}s)" } 200>>"$TIME_REPORT" # 文件描述符200指向报告文件 # 并行控制(同上,略) for sql_file in "${SQL_FILES[@]}"; do ((TOTAL++)) execute_sql "$sql_file" & if [[ $(jobs -r -p | wc -l) -ge $MAX_PARALLEL ]]; then wait -n fi done wait # 新增:生成统计摘要 echo -e "\n===== 执行时间统计 =====" awk -F',' ' NR==1 {next} # 跳过CSV头 { total += $4 if ($4 > max || NR==2) max = $4 if ($4 < min || NR==2) min = $4 } END { printf "平均耗时: %.2fs\n最长耗时: %ds (%s)\n最短耗时: %ds (%s)\n", total/(NR-1), max, max_file, min, min_file }' "$TIME_REPORT" ``` --- ### **主要改进说明** 1. **时间记录粒度** - 使用`date +%s`获取Unix时间戳,计算精确到秒的持续时间 - 记录开始时间结束时间到CSV文件 2. **并发安全写入** 通过`flock`命令锁定文件,避免多进程同时写入CSV导致的数据错乱 3. **自动生成统计报告** - 最终通过awk分析CSV文件,输出: - 平均耗时 - 最长/最短耗时及其对应SQL文件 - CSV文件可直接用Excel打开进行深度分析 4. **状态分类** 明确区分成功(`success`)、失败(`failed`)、超时(`timeout`)三种状态 --- ### **使用示例** ```bash $ ./parallel_sql_runner_with_time.sh [success] ./sql_scripts/query1.sql (耗时: 12s) [timeout] ./sql_scripts/query2.sql (耗时: 300s) ... ===== 执行结果 ===== 总任务数: 20 成功数: 18 失败数: 2 ===== 执行时间统计 ===== 平均耗时: 45.33s 最长耗时: 300s (heavy_query.sql) 最短耗时: 2s (simple_update.sql) ``` --- ### **扩展建议** 1. **毫秒级精度** 将`date +%s`改为`date +%s%3N`,同时修改持续时间计算: ```bash duration=$(( (end_time - start_time) / 1000 )) # 毫秒转秒 ``` 2. **可视化图表** 用Python读取CSV生成趋势图: ```python import pandas as pd df = pd.read_csv("logs/time_report.csv") df.plot(x='sql_file', y='duration_sec', kind='bar') ``` 3. **超时预警** 在CSV中添加阈值标记: ```bash if [ $duration -gt 60 ]; then echo "WARNING: 长时间任务 $sql_file" fi ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值