[英]Slow database query with like and join
我创建了一个基于 laminas 和 mezzio 的 php 项目和一个 MySQL 数据库来存储媒体文件。 只有 1400 个媒体文件,搜索速度非常慢(搜索结果需要几秒钟)。
我的桌子是
用户
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_id` int(11) NOT NULL,
`username` varchar(255) CHARACTER SET utf16 COLLATE utf16_unicode_ci NOT NULL,
`password` varchar(255) CHARACTER SET utf16 COLLATE utf16_unicode_ci NOT NULL,
`email` varchar(255) CHARACTER SET utf16 COLLATE utf16_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
);
角色
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`access` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
);
媒体
CREATE TABLE `media` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`order` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`filename` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`is_private` int(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
);
媒体关键字
CREATE TABLE `media_keyword` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`media_id` int(11) NOT NULL,
`keyword` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
);
媒体角色
CREATE TABLE `media_role` (
`media_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
PRIMARY KEY (`media_id`,`role_id`)
);
我正在使用 doctrine 创建查询,并且 followwing 查询用于搜索给定搜索查询的数据库:
SELECT DISTINCT m.*, u.username
FROM media AS m
LEFT JOIN user AS u ON u.id = m.user_id
LEFT JOIN media_keyword AS k ON k.media_id = m.id
LEFT JOIN media_role AS r ON m.id = r.media_id
WHERE (m.is_private = 0 OR (m.is_private = 1 AND m.user_id = :user_id))
AND (r.role_id = :role_id OR r.role_id IS NULL)
AND (m.filename LIKE :search OR m.title LIKE :search OR k.keyword LIKE :search)
GROUP BY m.id
LIMIT :offset, :page_size
当我通过 MySQL Workbench 直接查询数据库时,搜索查询大约需要 7-14 秒。 如果在 PHP / Lamins / Mezzio 应用程序中执行搜索,似乎需要更长的时间。
在我的本地机器上,它运行得非常快。 实时机器在搜索时从未超过 70% 的 CPU / RAM 使用率,所以我认为这不取决于硬件。
有人可以帮助我并告诉我我可以做些什么来提高性能吗?
解决方案是添加外键,以便数据库创建索引。 即使数据已经存在于表中,也可以添加外键。 从那时起,性能得到极大改善。
解释一下为什么我以前不使用外键:我想先使用代码并通过代码处理所有关系(删除约束等)。 事实证明这不是一个好主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.