早上好, 我有两张桌子,ANALISI有1462632条记录,PAZIENTE有1408146条记录,这个简单计数使用PAZIENTE索引之一需要大约30秒才能回馈大约65000条记录
SELECT COUNT(analisi0_.ID_ANALISI) AS col_0_0_
FROM Analisi analisi0_
INNER JOIN Paziente paziente1_ ON analisi0_.ID_PAZIENTE = paziente1_.ID_PAZIENTE
WHERE (paziente1_.nome LIKE 'MARIA%')
我也尝试在analisi0_.ID_PAZIENTE上添加一个索引,但效果不佳。 有没有办法提高性能?
这是对我来说似乎没问题的相应解释
CREATE TABLE ANALISI
(
ID_ANALISI INT UNSIGNED NOT NULL AUTO_INCREMENT,
ID_PAZIENTE INT UNSIGNED NOT NULL,
ID_SESSIONE INT UNSIGNED NOT NULL,
TRACCIATO TINYINT UNSIGNED NOT NULL,
CAMPIONE VARCHAR(30),
ID_PATOLOGICO TINYINT UNSIGNED,
REPARTO VARCHAR(40),
TOTALE_PROTEINE FLOAT,
RAPP_AG FLOAT,
ID_ANALISI_LINK INT UNSIGNED,
ID_ANALISI_IFE INT UNSIGNED,
ID_ANALISI_DATI INT UNSIGNED,
ID_ANALISI_NOTA INT UNSIGNED,
DATA_MODIFICA DATETIME,
ID_UTENTE_MODIFICA SMALLINT UNSIGNED,
DATA_VALIDAZIONE DATETIME,
ID_TIPO_VALIDAZIONE TINYINT UNSIGNED NOT NULL,
ID_UTENTE_VALIDAZIONE SMALLINT UNSIGNED,
DATA_CANCELLAZIONE DATETIME,
ID_UTENTE_CANCELLAZIONE SMALLINT UNSIGNED,
PRIMARY KEY (ID_ANALISI),
INDEX IDX_CAMPIONE (CAMPIONE),
INDEX IDX_REPARTO (REPARTO),
CONSTRAINT FK_ANALISI_PAZIENTE FOREIGN KEY (ID_PAZIENTE) REFERENCES PAZIENTE(ID_PAZIENTE),
CONSTRAINT FK_ANALISI_SESSIONE FOREIGN KEY (ID_SESSIONE) REFERENCES SESSIONE(ID_SESSIONE),
CONSTRAINT FK_ANALISI_PATOLOGICO FOREIGN KEY (ID_PATOLOGICO) REFERENCES PATOLOGICO(ID_PATOLOGICO),
CONSTRAINT FK_ANALISI_TIPO_VALIDAZIONE FOREIGN KEY (ID_TIPO_VALIDAZIONE) REFERENCES TIPO_VALIDAZIONE(ID_TIPO_VALIDAZIONE),
CONSTRAINT FK_ANALISI_UTENTE_MODIFICA FOREIGN KEY (ID_UTENTE_MODIFICA) REFERENCES UTENTE(ID_UTENTE),
CONSTRAINT FK_ANALISI_UTENTE_VALIDAZIONE FOREIGN KEY (ID_UTENTE_VALIDAZIONE) REFERENCES UTENTE(ID_UTENTE),
CONSTRAINT FK_ANALISI_UTENTE_CANCELLAZIONE FOREIGN KEY (ID_UTENTE_CANCELLAZIONE) REFERENCES UTENTE(ID_UTENTE),
CONSTRAINT FK_ANALISI_ANALISI_LINK FOREIGN KEY (ID_ANALISI_LINK) REFERENCES ANALISI(ID_ANALISI),
CONSTRAINT FK_ANALISI_ANALISI_IFE FOREIGN KEY (ID_ANALISI_IFE) REFERENCES ANALISI_IFE(ID_ANALISI_IFE),
CONSTRAINT FK_ANALISI_ANALISI_NOTA FOREIGN KEY (ID_ANALISI_NOTA) REFERENCES ANALISI_NOTA(ID_ANALISI_NOTA),
CONSTRAINT FK_ANALISI_ANALISI_DATI FOREIGN KEY (ID_ANALISI_DATI) REFERENCES ANALISI_DATI(ID_ANALISI_DATI)
)
ENGINE=InnoDB;
CREATE TABLE PAZIENTE
(
ID_PAZIENTE INT UNSIGNED NOT NULL AUTO_INCREMENT,
ID_PAZIENTE_LAB VARCHAR(20),
COGNOME VARCHAR(30),
NOME VARCHAR(30),
DATA_NASCITA DATE,
ID_SESSO TINYINT UNSIGNED NOT NULL,
RECAPITO VARCHAR(50),
CODICE_FISCALE VARCHAR(30),
ID_SPECIE TINYINT UNSIGNED NOT NULL,
PRIMARY KEY (ID_PAZIENTE),
INDEX IDX_DATA_NASCITA (DATA_NASCITA),
INDEX IDX_COGNOME (COGNOME),
INDEX IDX_NOME (NOME),
INDEX IDX_SESSO (ID_SESSO),
CONSTRAINT FK_PAZIENTE_SPECIE FOREIGN KEY (ID_SPECIE) REFERENCES SPECIE(ID_SPECIE),
CONSTRAINT FK_PAZIENTE_SESSO FOREIGN KEY (ID_SESSO) REFERENCES SESSO(ID_SESSO)
)
ENGINE=InnoDB;
答案 0 :(得分:1)
在InnoDB中,每个索引都隐式包含主键。
解释计划显示表IDX_NOME
上使用了索引Paziente
。 DBMS在索引中查找名称并在其中查找ID_PAZIENTE
,这是我们访问另一个表所需的密钥。所以没有什么可补充的。 (在另一个DBMS中,我们会在(NOME, ID_PAZIENTE)
上添加一个复合索引,以实现此目的。)
然后要考虑表Analisi
。我们通过FK_ANALISI_PAZIENTE
找到一条记录,其中包含用于查找匹配项的ID_PAZIENTE
,以及可用于访问该表的主键ID_ANALISI
,但这不是偶数必要的,因为我们从索引中获得了所需的所有信息。我们需要在表格中找到任何东西。 (同样,在另一个DBMS中,我们会在(ID_PAZIENTE, ID_ANALISI)
上添加一个复合索引以获得覆盖索引。)
所以发生的事情仅仅是:读取一个索引以便读取另一个索引以便计数。完善。没有什么可补充的。
我们可以用COUNT(analisi0_.ID_ANALISI)
替换COUNT(*)
,因为前者只说"计算ID_ANALISI
不为空的记录",这是始终是ID_ANALISI
是表格的主键。因此,使用后者更简单,并说“记录记录”#34;。但是,如果有的话,我不希望这会大大加快查询速度。
因此从查询的角度来看,没有什么可以加快速度。以下是我想到的更多事情: