简体   繁体   English

使用 like 和 join 进行缓慢的数据库查询

[英]Slow database query with like and join

I have created a php project based on laminas and mezzio with a MySQL database to stora media files.我创建了一个基于 laminas 和 mezzio 的 php 项目和一个 MySQL 数据库来存储媒体文件。 At only 1400 media files, the search is really slow (multiple seconds for search results).只有 1400 个媒体文件,搜索速度非常慢(搜索结果需要几秒钟)。

My tables are我的桌子是

user用户

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`)
);

role角色

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`)
);

media媒体

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`)
);

media_keyword媒体关键字

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`)
);

media_role媒体角色

CREATE TABLE `media_role` (
  `media_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`media_id`,`role_id`)
);

I am using doctrine to create the queries and the follogwing query is used to search the databse for a given search query:我正在使用 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

When I query the database directly via MySQL Workbench, a search query takes about 7-14 seconds.当我通过 MySQL Workbench 直接查询数据库时,搜索查询大约需要 7-14 秒。 It seems that it takes even longer if the search is executed in the PHP / Lamins / Mezzio application.如果在 PHP / Lamins / Mezzio 应用程序中执行搜索,似乎需要更长的时间。

On my local machine it works pretty fast.在我的本地机器上,它运行得非常快。 The live machine has never more then 70% usage of CPU / RAM on a search, so I don't think it is depending on hardware.实时机器在搜索时从未超过 70% 的 CPU / RAM 使用率,所以我认为这不取决于硬件。

Can someone help me please and tell me what I could do to improve performance?有人可以帮助我并告诉我我可以做些什么来提高性能吗?

The solution was to add Foreign Keys so that Indexes are created by the database.解决方案是添加外键,以便数据库创建索引。 It was possible to add the Foreign Keys even with data already existing in the table.即使数据已经存在于表中,也可以添加外键。 Since then the performance was extremely improved.从那时起,性能得到极大改善。

To explain why I didn't use Foreign Keys before: I wanted to use code first and handle all relations via code (delete constraints etc.).解释一下为什么我以前不使用外键:我想先使用代码并通过代码处理所有关系(删除约束等)。 It turned out that this was not a good idea.事实证明这不是一个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM