两个视图中用到同一个表,然后两个视图之间有关联关系,查询效率非常低,like一个字段时,大概需要十几秒
如果在两个视图中使用同一个表,并且这两个视图之间存在关联关系,那么在进行查询或更新操作时,可能会出现性能下降的情况。这主要是因为数据库需要在进行查询或更新操作时,对表进行大量的计算和索引操作,以维护数据的一致性和完整性。
具体来说,当一个视图中需要对表进行查询或更新操作时,数据库需要先查询出该表中的所有数据,并在内存中构建数据模型。然后,根据第一个视图中的条件,对数据模型进行筛选和排序,得到符合条件的数据。接着,根据第二个视图中的条件,对数据模型进行进一步的筛选和排序,得到符合条件的数据。这个过程需要不断地进行计算和索引操作,会消耗大量的计算资源,从而导致性能下降。
因此,如果两个视图中用到同一个表,并且两个视图之间存在关联关系,建议尽可能减少对表的查询和更新操作,或者考虑对表进行分区或索引优化,以提高数据库的性能。
重新建立视图,将需要的字段内容,合为一个新视图,避免用到两次表,导致效率非常低,调整后like查询只需要。0.1秒就可以完成查询
centos 7.6 内存16g 硬盘500g cpu>8 核心数>2
输入命令cat /etc/selinux/config,查看SELINUX配置项,如果不是disabled,需修改
方式1:对于linux vi命令不熟悉的
方式2:使用vi操作修改文件
1.在/opt目录下创建software文件夹 2.将docker-19.03.6.tgz上传至此文件夹中,即/opt/software目录 3.执行命令进入此文件夹,
cd /opt/software
4.执行解压命令:
tar xzvf docker-19.03.6.tgz
5.执行命令:
cp docker/* /usr/bin/
此命令的作用是将解压出来的docker文件夹中的所有文件拷贝至/usr/bin目录下 cd /usr/bin/ 6.执行命令:
dockerd &
启动docker 7.执行命令:
docker info
查看是否已安装成功 至此,如上图所示docker已安装完成,为了让docker可受systemctl命令控制,我们还可以做进一步扩展:
8.执行命令:
cp docker.socket /etc/systemd/system cp docker.service /etc/systemd/system
命令的作用是将docker.service和docker.socket文件拷贝至/etc/systemd/system目录
9.重启 systemctl 守护进程
执行命令:
systemctl daemon-reload
10.将docker 服务加入开机自启动:
执行命令:
systemctl enable docker
在项目中经常会使用到存储过程,来优化sql语句,比如获取两个时间差的日期等,减少sql的复杂性
sql
--创建函数
CREATE OR REPLACE FUNCTION 函数名(参数1 模式 参数类型)
RETURN 返回值类型
AS
变量1 变量类型;
变量2 变量类型;
BEGIN
函数体;
END 函数名;
其他语法
sql--删除函数
DROP FUNCTION 函数名;
--确定函数状态
SELECT OBJECT_NAME FROM USER_OBJECTS WHERE STATUS='INVALID' AND OBJECT_TYPE='FUNCTION';
--编译函数
ALTER FUNCTION 函数名 COMPILE;
--查看函数代码
SELECT TEXT FROM USER_SOURCE WHERE NAME='函数名';
sql--创建函数
CREATE OR REPLACE FUNCTION F_CUR_DATETIME
RETURN VARCHAR2
IS
BEGIN
RETURN TO_CHAR(SYSDATE,'YYYY"年"MM"月"DD"日"HH24"时"MI"分"SS"秒"');
END;
--调用函数方式1
SELECT F_CUR_DATETIME() FROM DUAL;
--调用函数方式2
BEGIN
DBMS_OUTPUT.PUT_LINE(F_CUR_DATETIME);
END;
sqlCREATE OR REPLACE FUNCTION GET_SAL(NAME VARCHAR2)
RETURN NUMBER
AS
V_SAL EMP.SAL%TYPE;
BEGIN
SELECT SAL INTO V_SAL FROM EMP WHERE UPPER(ENAME)=UPPER(NAME);
RETURN V_SAL;
END;
--调用函数
BEGIN
DBMS_OUTPUT.PUT_LINE(GET_SAL(NAME => 'SMITH'));
END;
sqlCREATE OR REPLACE FUNCTION GET_NAME(ENO NUMBER,OJOB OUT VARCHAR2)
RETURN VARCHAR2
AS
NAME EMP.ENAME%TYPE;
BEGIN
SELECT ENAME,JOB INTO NAME,OJOB FROM EMP WHERE EMPNO=ENO;
RETURN NAME;
END;
--调用函数
DECLARE
V_NAME EMP.ENAME%TYPE;
V_JOB EMP.JOB%TYPE;
BEGIN
V_NAME:=GET_NAME(ENO=>7900,OJOB => V_JOB);
DBMS_OUTPUT.PUT_LINE('姓名:'||V_NAME||',工作:'||V_JOB);
END;
sql
create or replace function GET_OVERDUE_DAYS(patientId in varchar2,
visitNo in varchar2)
return number is
VD_OVERDUE_DAYS number;
VD_DISCHARGE_TIME DATE;
VD_RECEIVE_TIME DATE;
VD_EXSIT_REC number;
begin
--获取逾期天数
select t.discharge_date_time INTO VD_DISCHARGE_TIME from pat_visit t where t.patient_id= patientId and t.visit_id = visitNo;
select count(1) into VD_EXSIT_REC from rec_mr_index t where t.patient_id=patientId and t.visit_no = visitNo;
if VD_EXSIT_REC >0 then
select t.receive_time into VD_RECEIVE_TIME from rec_mr_index t where t.patient_id=patientId and t.visit_no = visitNo;
if VD_RECEIVE_TIME is null then
VD_RECEIVE_TIME:=sysdate;
end if;
else
VD_RECEIVE_TIME:=sysdate;
end if;
SELECT FLOOR(VD_RECEIVE_TIME - VD_DISCHARGE_TIME) - 7 INTO VD_OVERDUE_DAYS FROM DUAL;
if VD_OVERDUE_DAYS < 0 then
VD_OVERDUE_DAYS:= 0;
end if;
return(VD_OVERDUE_DAYS);
end GET_OVERDUE_DAYS;
由于业务需要,前端传递已经配置好的sql,所以我需要实现一个通用的动态查询方案
controller
java//contorller
@ApiOperation(value = "执行指定sql的脚本")
@PostMapping("getSqlScriptExcuteResult")
public Result<Object> getSqlScriptExcuteResult(@RequestBody @Validated RecSearchSolutionSqlScriptExcuteResultRequest request) {
List<Map<String, Object>> map = iRecSearchSolutionService.getSqlScriptExcuteResult(request);
return Result.success(map);
}
service层
java//Service
List<Map<String, Object>> getSqlScriptExcuteResult(RecSearchSolutionSqlScriptExcuteResultRequest request);
impl层
java//impl
@Override
public List<Map<String, Object>> getSqlScriptExcuteResult(RecSearchSolutionSqlScriptExcuteResultRequest request) {
if (request.getPage() != 0 && request.getRows() != 0) {
Integer begin= (request.getPage()-1)*request.getRows();
Integer end=request.getPage()*request.getRows();
String newSql = MessageFormat.format("SELECT *\n" +
" FROM (SELECT TMP.*, ROWNUM ROW_ID\n" +
" FROM (" +
"{0}" +
") TMP\n" +
" WHERE ROWNUM <= {1})\n" +
" WHERE ROW_ID > {2}\n", request.getSql(),end,begin);
request.setSql(newSql);
}
logger.info(request.getSql());
List<Map<String, Object>> map = commonService.queryForMapList(request.getSql());
for (Map<String,Object> m: map) {
for (Map.Entry<String, Object> set:m.entrySet()) {
if (set.getValue() instanceof Date){
set.setValue(DateUtil.format((Date)set.getValue(),"yyyy-MM-dd HH:mm:ss"));
}
}
}
return map;
}
commonService
javapackage com.lhw.service;
import com.lhw.mapper.SqlHelperMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Service
public class CommonService {
@Resource
private JdbcTemplate jdbcTemplate;
@Resource
private SqlHelperMapper sqlHelperMapper;
public String queryForString(String sql) {
List<String> list = jdbcTemplate.queryForList(sql, String.class);
if (list.size() == 0) {
return "";
} else {
return list.get(0);
}
}
public List<String> queryForStringArray(String sql) {
List<String> list = jdbcTemplate.queryForList(sql, String.class);
return list;
}
public List<Date> queryForDateArray(String sql) {
List<Date> list = jdbcTemplate.queryForList(sql, Date.class);
return list;
}
public Integer queryForInt(String sql) {
List<Integer> list = jdbcTemplate.queryForList(sql, Integer.class);
if (list.size() == 0) {
return 0;
} else {
return list.get(0);
}
}
public Date queryForDate(String sql) {
List<Date> list = jdbcTemplate.queryForList(sql, Date.class);
if (list.size() == 0) {
return new Date();
} else {
return list.get(0);
}
}
public <T> List<T> queryForList(String sql,Class<T> elementType ){
List<T> list= jdbcTemplate.queryForList(sql, elementType);
return list;
}
public <T> List<T> query(String sql,RowMapper<T> rowMapper){
return jdbcTemplate.query(sql,rowMapper);
}
public List<LinkedHashMap<String, Object>> superSelect(String sql) {
return sqlHelperMapper.superSelect(sql);
}
public Integer superSelectForInt(String sql) {
return sqlHelperMapper.superSelectForInt(sql);
}
public List<Map<String, Object>> queryForMapList(String sql) {
return jdbcTemplate.queryForList(sql);
}
}
使用queryForList,会提示Incorrect column count: expected 1, actual 2,因为只支持返回一个list 所以我们就需要在commonService里调整,直接使用query
java public List<SolutionConditionDictResponse> queryForDictList(String sql) {
return jdbcTemplate.query(sql,BeanPropertyRowMapper.newInstance(SolutionConditionDictResponse.class));
}
由于业务要求需要根据list里的时间排序来再次进行排序
在Java中,你可以使用Collections.sort()方法对List中的元素进行排序。如果要按照时间排序,你需要确保每个元素都包含一个对应的时间戳或日期对象,并使用Comparator接口定义的比较方法来比较元素的时间戳或日期。
java//升序
Collections.sort(emrDocVEntityList, new Comparator<EmrDocVRes>() {
@Override
public int compare(EmrDocVRes o1, EmrDocVRes o2) {
return o1.getDocTime().compareTo(o2.getDocTime());
}
});