MariaDB -SELECT和2 JOIN的索引使用不一致

bhmjp9jg  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(121)

我正在尝试从我的生产站点重新创建一个本地开发环境。使用MariaDB 10.3。
我已经将生产环境(结构、索引和数据)复制到了本地机器上,但不幸的是,我无法获得与生产环境相当的性能。

问题

当我运行以下查询时,我在两个env之间获得了非常不同的性能(dev上12秒,prod上30毫秒):

SELECT DISTINCT UPPER(LEFT(t.title, 1))
FROM elenco AS e
JOIN title_list AS t ON e.codice = t.release_code
JOIN login AS l ON e.gruppo = l.gruppo
WHERE e.materiale = 'film' AND l.id_utente = 1 AND t.title_type = 'ITA'
ORDER BY t.title

当我EXPLAIN查询时,我在两个环境中得到不一致的结果:

PROD

| ID|选择类型|表|类型|可能键|关键|键透镜|ref|行|额外|
| --|--|--|--|--|--|--|--|--|--|
| 1 |简单|L| const|初级|初级| 4 |const| 1 |使用临时|
| 1 |简单|不|指数|PRIMARY,title_type|标题| 514 || 200 |用where|
| 1 |简单|e| eq_ref|初级|初级| 4 |my_IUB.t.release_code| 1 |使用where;不同|

DEV

| ID|选择类型|表|类型|可能键|关键|键透镜|ref|行|额外|
| --|--|--|--|--|--|--|--|--|--|
| 1 |简单|L| const|初级|初级| 4 |const| 1 |使用临时;使用文件排序|
| 1 |简单|不|全部| PRIMARY,title_type|||| 9788 |用where|
| 1 |简单|e| eq_ref|初级|初级| 4 |my_iub.t.release_code| 1 |使用where;不同|

表详情

elenco

CREATE TABLE `elenco` (
  `codice` int(10) NOT NULL AUTO_INCREMENT,
  `materiale` varchar(25) NOT NULL,
  `gruppo` int(11) NOT NULL DEFAULT 0,
  `autore` int(10) NOT NULL,
  PRIMARY KEY (`codice`)
) ENGINE=MyISAM AUTO_INCREMENT=8908 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

title_list

CREATE TABLE `title_list` (
  `release_code` int(11) NOT NULL,
  `title` varchar(512) NOT NULL,
  `title_type` varchar(64) NOT NULL COMMENT 'Can be: ORIGINAL or ITA',
  `last_modify` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT 'It''s the time the release title was modifid',
  PRIMARY KEY (`release_code`,`title_type`),
  KEY `title` (`title`),
  FULLTEXT KEY `title_type` (`title_type`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='It''s the list of all titles';

login

CREATE TABLE `login` (
  `id_utente` int(10) NOT NULL AUTO_INCREMENT,
  `user` varchar(65) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL COMMENT 'Recovery email',
  `passw` varchar(256) DEFAULT NULL,
  `permessi` int(11) NOT NULL DEFAULT 99,
  `gruppo` int(11) NOT NULL DEFAULT 1,
  `attivazione` varchar(256) NOT NULL,
  `ultima_modifica` datetime NOT NULL DEFAULT current_timestamp(),
  `online` datetime NOT NULL DEFAULT current_timestamp(),
  `last_time_online` datetime NOT NULL DEFAULT current_timestamp(),
  `premium_1f` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`id_utente`),
  UNIQUE KEY `attivazione` (`attivazione`),
  UNIQUE KEY `user` (`user`),
  UNIQUE KEY `user_2` (`user`)
) ENGINE=MyISAM AUTO_INCREMENT=66 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

title_list对于两个环境SHOW INDEXES FROM title_list;具有相同的索引:
| 表名|非唯一|公司简介|序列号索引|列名称|整理|基数|联系我们| Package |可空|索引_类型|评论|首页_评论|
| --|--|--|--|--|--|--|--|--|--|--|--|--|
| 标题列表| 0 |初级| 1 |释放码|一| 9788 ||||BTREE|||
| 标题列表| 0 |初级| 2 |标题类型|一| 9788 ||||BTREE|||
| 标题列表| 1 |标题| 1 |标题|一| 9788 ||||BTREE|||
| 标题列表| 1 |标题类型| 1 |标题类型|| 1 ||||FULLTEXT|||
我尝试了什么?

  • 切换到MariaDB 10.4或更高版本并没有解决我的问题
  • 删除和重新创建索引并没有解决我的问题
  • elencotitle_list上强制使用索引部分地提高了性能(从12秒到3秒)

趣事

  • 开发环境(较慢的)是在英特尔i7上,16 GB RAM和SSD
  • 生产环境(速度更快的一个)是在一个Raspberry pi 4上,具有4GB RAM,并使用通过USB插入的机械HD
hiz5n14c

hiz5n14c1#

这些索引可以加快两台服务器上的查询速度:

t:  INDEX(title_type, release_code, title)
e:  INDEX(materiale, codice,  gruppo)
l:  INDEX(id_utente, gruppo)

如果数据不同(在dev和prod之间),这可以解释不同的计时和查询执行计划。请提供每台机器的EXPLAIN SELECT ...
切换到InnoDB。执行大量的DELETEsUPDATEs等,会导致MyISAM比InnoDB更糟糕的碎片化。
建议更改为ORDER BY 1--因为您实际上只是按title的第一个字母的“0”排序。
对每台计算机上的每个表运行ANALYZE TABLE。这 * 可能 * 使它们工作相同和/或 * 可能 * 加快一个或两个。

相关问题