我遇到一个优化问题,我不知道为什么我的查询这么慢。
在生产中搜索文档时。name
当没有结果且没有IDX_DOC_name_UPPER
时,应用程序大约需要4分钟。使用IDX_DOC_NAME_UPPER
时,它的变化范围从40秒到2米。在sqlplus中,有索引和没有8-9大约需要3-4秒。
文档
包含约200万条记录和活动
700万条记录。
-- DOCUMENTS
CREATE TABLE DOCUMENTS
(
ID NUMBER(16) PRIMARY KEY,
NAME VARCHAR(1024) NOT NULL,
DOC_SIZE NUMBER(16) NOT NULL,
CREATED TIMESTAMP NOT NULL
);
CREATE INDEX IDX_DOC_NAME_UPPER ON DOCUMENTS (UPPER(NAME));
-- USERS
CREATE TABLE USERS
(
ID NUMBER(16) PRIMARY KEY,
CNAME VARCHAR(256) NOT NULL
--others, removed for brevity
);
-- ACTIVITIES
CREATE TABLE ACTIVITIES
(
ID NUMBER(16) PRIMARY KEY,
USR_ID NUMBER(16) references USERS (ID) NOT NULL,
DOC_ID NUMBER(16) references DOCUMENTS (ID),
PRT_ID NUMBER(16) references USERS (ID) NOT NULL
--others, removed for brevity
);
CREATE INDEX IDX_ACT_USR_ID ON ACTIVITIES (USR_ID);
CREATE INDEX IDX_ACT_DOC_ID ON ACTIVITIES (DOC_ID);
-- LOGS
CREATE VIEW V_LOGS AS
SELECT CNAME,
ACTIVITIES.USR_ID,
PRT_ID,
DOC_ID
--others, removed for brevity
FROM ACTIVITIES,
USERS
WHERE USERS.ID = ACTIVITIES.USR_ID;
@Data
@Entity
@NoArgsConstructor
@Table(name = "USERS")
@SequenceGenerator(allocationSize = 1, name = "USERS_ID", sequenceName = "USERS_ID")
public class User {
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_ID")
private Long id;
@NotNull
@Column(name = "CNAME", nullable = false, length = 256)
private String cname;
}
@Entity
@Getter
@Immutable
@Table(name = "V_LOGS")
public class LogsView {
@Id
@Column(name = "USR_ID", nullable = false)
private long usrId;
@Column(name = "PRT_ID", nullable = false)
private long prtId;
@Column(name = "DOC_ID")
private Long docId;
@ManyToOne
@JoinColumn(name = "USR_ID",
nullable = false,
insertable = false,
updatable = false)
private User user;
@ManyToOne
@JoinColumn(name = "PRT_ID",
nullable = false,
insertable = false,
updatable = false)
private User partner;
@ManyToOne
@JoinColumn(name = "DOC_ID",
insertable = false,
updatable = false)
private Document document;
//others, removed for brevity
}
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "DOCUMENTS")
@SequenceGenerator(allocationSize = 1, name = "DOCUMENTS_ID", sequenceName = "DOCUMENTS_ID")
public class Document {
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DOCUMENTS_ID")
private Long id;
@Column(name = "NAME", nullable = false, length = 1024)
private String name;
@Column(name = "DOC_SIZE", nullable = false)
private long size;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "CREATED", nullable = false)
private Date created;
//others, removed for brevity
}
@RequiredArgsConstructor
public class LogsSpecification implements Specification<LogsView> {
private final List<SimpleFilter> filters;
@Override
public Predicate toPredicate(Root<LogsView> root,
CriteriaQuery<?> criteriaQuery,
CriteriaBuilder criteriaBuilder) {
if (CollectionUtils.isEmpty(filters)) return null;
Predicate[] predicates = filters.stream()
.filter(Objects::nonNull)
.map(filter -> getPredicate(filter, root, criteriaBuilder))
.toArray(Predicate[]::new);
return criteriaBuilder.and(predicates);
}
private Predicate getPredicate(SimpleFilter filter,
Root<LogsView> root,
CriteriaBuilder builder) {
Objects.requireNonNull(filter.getName());
Predicate predicate;
String[] keys = filter.getName().split("\\.");
if (filter.getPredicate() == LIKE) {
predicate = builder.like(
builder.upper(PredicateUtils.getChildPath(root, keys)),
("%" + filter.getValue() + "%").toUpperCase());
} else {
predicate = builder.equal(
PredicateUtils.getChildPath(root, keys),
filter.getValue());
}
//others, removed for brevity
return predicate;
}
}
@Repository
public interface LogsRepository extends ReadOnlyRepository<LogsView, Long>, JpaSpecificationExecutor<Logs> {}
@Service
@RequiredArgsConstructor
public class LogsService {
private final LogsRepository logsRepository;
private final ObjectMapper mapper;
private final Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?");
public Page<LogsDto> paginated(String name, String value) {
var type = isNumeric(value) ? SimpleFilter.PredicateType.EQUAL : SimpleFilter.PredicateType.LIKE;
var filter = new SimpleFilter(name, value, type);
return logsRepository
.findAll(new LogsSpecification(List.of(filter)), Pageable.ofSize(10))
.map(en -> mapper.convertValue(en, LogsDto.class));
}
private boolean isNumeric(String strNum) {
return strNum != null && pattern.matcher(strNum).matches();
}
}
-- Hibernate:
-- executing 5 JDBC statements;
select *
from (select * -- removed for brevity
from v_logs v_logs0_
cross join documents document1_
where v_logs0_.doc_id = document1_.id
and (
upper(document1_.name) like ?
)
and (
v_logs0_.usr_id in (4, 72, 76, 123, 147, 199, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)
)
and v_logs0_.usr_id <> 1
order by v_logs0_.usr_id asc)
where rownum <= ?
1.228738106 seconds
2.900642325 seconds
Without IDX_DOC_NAME_UPPER: 240.123813697 seconds, sqlpus: 8-9 seconds
With IDX_DOC_NAME_UPPER: 110.123813697(not stable), seconds sqlpus: 3-4 seconds
我用代码结构重新创建了一个简单的应用程序,你可以在这个链接找到它:demo-oracle-low。
谢谢
另一个选项是尝试创建一个反向文本索引,以防您的名称字段由几个单词组成。请参见CTXCAT索引留档。请注意,表内存空间将显著增加。
问题内容: 这是查询(最大的表约有40,000行) 如果运行此命令,它将很快执行(大约.05秒)。它返回13行。 当我在查询末尾添加一个子句(按任意列排序)时,查询大约需要10秒钟。 我现在正在生产中使用此数据库,并且一切正常。我所有其他查询都很快。 有什么想法吗?我在MySQL的查询浏览器中并从命令行运行了查询。两个地方都死了。 编辑: Tolgahan ALBAYRAK解决方案有效,但是谁能解
问题内容: 可以说我有这样的第一张桌子 分支表 第二张桌子是这样的 余额表 我想查询余额表,其中每一行包含分支表的名称。例如分支表中的“ 123456ABC”,我想从余额表中获取“ ABC”行 我怎样才能做到这一点?到目前为止,我还没有尝试过这个查询 有什么建议吗? 问题答案: 你应该 转换 了的名称模式: 联接看起来更易读:
问题内容: 我有一个PostgreSQL函数,可以将查询结果返回到pgadmin结果网格中。在内部,这是一个简单的函数,使用a连接到另一个数据库并返回查询,以便我可以简单地运行 它的运行就像基本的表查询一样。 问题是当我使用该子句时。因此,我想运行以下查询,但它要花很多时间: 我怎样才能加快速度?有什么比这种情况下的子句快的吗? 问题答案: 不是表-可能是一些存储过程,因此查询并不是很简单。您需要
我需要向MongoDB查询字段的编号:姓名、电话、电子邮件。查询应该支持语法:执行查询的更好方法是什么: 用$或查询字段数 用上述字段的值和该字段的多键索引创建数组字段 示例集合包含以下文档 当我发现所有带有姓名、电话或电子邮件且包含的文档时,应返回文档1和3。
问题内容: 我正在使用Google BigQuery,并且正在从PHP执行一些简单的查询。(例如,从电子邮件中的SELECT * WHERE email='mail@test.com‘)我只是在检查表中是否存在该电子邮件。 表“电子邮件”目前为空。但是,PHP脚本仍然需要大约4分钟的时间来检查一个空表上的175封电子邮件。.如我希望将来该表将被填充,并且将有500 000封邮件,那么我想请求时间会
我试图在mongodb日志文件中只记录慢速查询(执行时间超过10秒)。 我在运行蒙戈作为 并将分析设置为 但是当跟踪日志文件时,它会打印所有的查询。我可以看到很多查询,它的运行时间为0ms。我还需要添加什么来只获得慢速查询吗?