簡體   English   中英

Spring數據查詢非常慢

[英]Spring Data query is VERY slow

我有一個Spring Boot項目設置為將MySQL數據庫與Hibernate一起使用。 最近,我向數據庫表中添加了3萬個新條目,從那以后,查詢的速度就變得非常慢。

我使用查詢DSL自己執行查詢。 假設我具有以下與CandidateField實體具有OneToMany關系的Candidate實體:

@Entity
@Table(name = "Candidates", schema = "Candidate")
public class Candidate {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CandidateID")
private Long candidateID;
@Column(name = "FirstName")
private String firstName;
@Column(name = "LastName")
private String lastName;
@Column(name = "Zip")
private String zip;
@Column(name = "Email")
private String email;

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "candidate")
private List<CandidateField> fields;

//Constructors, getters, setters omitted

CandidateField實體:

@Entity
@Table(name = "CandidateFields", schema = "Candidate")
public class CandidateField {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CandidateFieldID")
@JsonIgnore
private Long candidateFieldID;
@JsonIgnore
@Column(name = "CandidateID")
private Long candidateID;
@Column(name = "Name")
private String name;
@ManyToOne
@JoinColumn(name = "CandidateID", referencedColumnName = "CandidateID", insertable = false, updatable = false)
@JsonIgnore
private Candidate candidate;

//Constructors, getters, setters omitted

最后,這是我的搜索代碼:

@Autowired
CandidateRepository repository;
QCandidate candidate = QCandidate.candidate;
BooleanExpression predicate = candidate.fields.any().name.eq("Accounting");
Iterable<Candidate> results = repository.findAll(predicate);

最后一行大約需要8分鍾來搜索30k記錄數據庫(沒有索引字段),結果是80行。 這個問題在本地和我的在線登台服務器中都相同。 它生成此查詢,然后暫停8分鍾:

select candidate0_.CandidateID as Candidat1_4_, candidate0_.Email as
Email7_4_, candidate0_.FirstName as FirstNam8_4_, candidate0_.LastName as
LastNam17_4_, candidate0_.Zip as Zip30_4_ from Candidate.Candidates
candidate0_where exists (select 1 from Candidate.CandidateFields fields1_
where candidate0_.CandidateID=fields1_.CandidateID and fields1_.Name=?)
binding parameter [1] as [VARCHAR] - [Accounting]

編輯:該問題肯定源於自動生成的查詢中的EXISTS子句。 現在,我必須研究為什么這樣做以及如何使其生成更有效的查詢

奇怪的是,如果我執行一個沒有任何參數的簡單findAll(),它實際上似乎是在選擇和解析結果,而不是暫停。 如果我按ID而不是Name搜索,問題仍然存在。

在我的數據庫管理工具中運行實際的SQL查詢會在大約1秒鍾內返回結果(這是根據要求提供EXPLAIN結果的查詢):

EXPLAIN SELECT *
FROM Candidates
INNER JOIN Candidate.CandidateFields
WHERE CandidateFields.CandidateID = Candidates.CandidateID AND 
CandidateFields.Name = "Accounting";

結果:

 <table> <tr> <th>id</th> <th>select_type</th> <th>table</th> <th>partitions</th> <th>type</th> <th>possible_keys</th> <th>key</th> <th>key_len</th> <th>ref</th> <th>rows</th> <th>filtered</th> <th>extra</th> </tr> <tr> <td>1</td> <td>SIMPLE</td> <td>CandidateFields</td> <td>null</td> <td>ALL</td> <td>null</td> <td>null</td> <td>null</td> <td>null</td> <td>30601</td> <td>10</td> <td>Using where</td> </tr> <tr> <td>1</td> <td>SIMPLE</td> <td>Candidates</td> <td>null</td> <td>eq_ref</td> <td>PRIMARY</td> <td>PRIMARY</td> <td>4</td> <td>Candidate.CandidateFields.CandidateID</td> <td>1</td> <td>100</td> <td>Using where</td> </tr> </table> 

編輯:該問題肯定源於自動生成的查詢中的EXISTS子句。 現在,我必須研究為什么這樣做以及如何使其生成更有效的查詢

希望得到任何幫助。 也可以澄清是否需要。 干杯!

沒有索引字段

為什么不? 只需在此處添加此索引:

CREATE INDEX i1 ON Candidate.CandidateFields(Name);

對於這個特定查詢甚至更快:

CREATE INDEX i2 ON Candidate.CandidateFields(Name, CandidateID);

因為后者將成為半EXISTS()子查詢)的覆蓋索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM