MySQL GROUP BY 函数需要很多时间

标签 mysql performance optimization group-by

我一直在使用以下查询搜索一些数据。我是新手。如果有任何设计错误,请原谅。

SELECT
    j.applicant_uid,
    j.job_id,u.id,
    MAX(u.name),
    ui.phone,
    ui.fullname,
    ui.img,
    ui.address,
    u.r_date,
    r.sex,
    r.present_salary,
    w.working,
    w.description,
    e.institute_name,
    e.exam_name,
    ROUND(DATEDIFF(w.time_start, w.time_end) / 365.25) AS experience,
    ROUND(DATEDIFF(CURDATE(),r.dob) / 365.25) AS age,
    r. preferred_district,
    e.major_group ,
    w.compnay_name,
    w.designation,
    j.ukey
FROM job_apply as j               
INNER JOIN users u            ON j.applicant_uid = u.id
INNER JOIN resume r           ON j.applicant_uid = r.uid
INNER JOIN work_history w     ON j.applicant_uid = w.uid 
INNER JOIN education e        ON j.applicant_uid = e.uid
INNER JOIN user_other_info ui ON j.applicant_uid = ui.uid
WHERE `j.job_id`='131'
  AND `r.sex`                 LIKE '%1%'
  AND  `r.preferred_district` LIKE '%14%'
  AND `w.description`         LIKE '%brac%'
   OR `e.exam_name`           LIKE '%brac%'
   OR `w.compnay_name`        LIKE '%brac%'
   OR `w.designation`         LIKE '%brac%'
   OR `e.institute_name`      LIKE '%brac%'
GROUP BY `u.id`
HAVING `experience` >= '1'
  AND `r.present_salary` BETWEEN '15000' AND '20000'

但是大约需要30.017秒。如何减少查询时间?可能是什么原因?我添加了别名。

    CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(500) NOT NULL,
    `role_type` int(11) NOT NULL,
    `user_type` int(3) NOT NULL,
    `umail` varchar(100) NOT NULL,
    `user_pass` varchar(100) NOT NULL,
    `block` int(2) NOT NULL DEFAULT '0',
    `r_date` date NOT NULL,
    `u_date` date NOT NULL,
     PRIMARY KEY (`id`)
     ) ENGINE=InnoDB AUTO_INCREMENT=4560 DEFAULT CHARSET=latin1

这是简历表:

    CREATE TABLE `resume` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `uid` int(11) NOT NULL,
 `career_objective` varchar(5000) CHARACTER SET utf8 NOT NULL,
 `father` varchar(100) CHARACTER SET utf8 NOT NULL,
 `mother` varchar(100) CHARACTER SET utf8 NOT NULL,
 `dob` date NOT NULL DEFAULT '0000-00-00',
 `birth_place` varchar(100) CHARACTER SET utf8 NOT NULL,
 `nationality` varchar(100) CHARACTER SET utf8 NOT NULL,
 `sex` varchar(50) CHARACTER SET utf8 NOT NULL,
 `looking_for` int(3) NOT NULL,
 `present_salary` varchar(100) CHARACTER SET utf8 NOT NULL,
 `expected_salary` varchar(10) CHARACTER SET utf8 NOT NULL,
 `preferred_category` varchar(10) CHARACTER SET utf8 NOT NULL,
 `preferred_district` varchar(10) CHARACTER SET utf8 NOT NULL,
 `declaration` varchar(1000) CHARACTER SET utf8 NOT NULL,
 `facebook_link` varchar(1000) CHARACTER SET utf8 NOT NULL,
 `linkedin_link` varchar(1000) CHARACTER SET utf8 NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1905 DEFAULT CHARSET=latin1

以下是:

    CREATE TABLE `education` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `uid` int(11) NOT NULL,
 `institute_name` varchar(500) CHARACTER SET utf8 NOT NULL,
 `exam_name` varchar(100) CHARACTER SET utf8 NOT NULL,
 `major_group` varchar(100) CHARACTER SET utf8 NOT NULL,
 `result` varchar(100) CHARACTER SET utf8 NOT NULL,
 `passing_year` varchar(100) CHARACTER SET utf8 NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5279 DEFAULT CHARSET=latin1

这是 job_apply 表。请考虑数据库设计错误:

    CREATE TABLE `job_apply` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `job_id` int(11) NOT NULL,
 `applicant_uid` int(11) NOT NULL,
 `ukey` varchar(50) NOT NULL,
 `date` date NOT NULL,
 `is_short_list` int(2) NOT NULL DEFAULT '0',
 `is_rejected` int(2) NOT NULL DEFAULT '0',
 `note` varchar(5000) CHARACTER SET utf8 NOT NULL,
 `cv_viewed` int(11) NOT NULL DEFAULT '0',
 `ssc_certificate` varchar(500) CHARACTER SET utf8 NOT NULL,
 `ssc_marksheet` varchar(500) CHARACTER SET utf8 NOT NULL,
 `hsc_certificate` varchar(500) CHARACTER SET utf8 NOT NULL,
 `hsc_marksheet` varchar(500) CHARACTER SET utf8 NOT NULL,
 `graduation_certificate` varchar(500) CHARACTER SET utf8 NOT NULL,
 `graduation_marksheet` varchar(500) CHARACTER SET utf8 NOT NULL,
 `experience_certificate` varchar(500) CHARACTER SET utf8 NOT NULL,
 `recommendation_letter` varchar(500) CHARACTER SET utf8 NOT NULL,
 `ans` varchar(5000) CHARACTER SET utf8 NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2079 DEFAULT CHARSET=latin1

最佳答案

这里有几个问题,但有一个问题很明显:您使用了“%brac%”等通配符模式。请理解,“brac%”可以利用索引,但带有前导百分号的通配符则不能。您正在强制进行表扫描。似乎有几个。

您制作了present_salary varchar(100),而不是数字,这似乎是一个极其糟糕的设计选择。如果您请求 '9000' 和 '11000' 之间的行,则会导致麻烦,因为字典顺序与数字顺序不同。

请编辑您的问题以包含 SHOW CREATE TABLE job_apply 的输出,以及用户、简历、work_history、教育和 user_other_info。描述大概的表大小,也许有几千行。最重要的是,一定要包括 EXPLAIN输出,以便我们看到后端优化器确定的计划。

您在多个位置加入了 uid,但您选择不向优化器提供其中任何一个的索引,因此它被迫进行表扫描。您没有包含 EXPLAIN 输出,但从架构中可以清楚地看出您无法利用选择性,并且必须扫描所有表。

感谢您添加的格式,这非常有帮助。

拼写错误:w.compnay_name

您有一堆 latin1 表,这很好,但您可能更愿意选择默认的 utf8 表。令人不安的是你混合使用 latin1 和 utf8 varchars。最好选择一个,例如utf8。您严格按照整数 uid 进行联接,但如果您要对文本列进行等联接,则需要相同的排序规则和相同的字符集才能正确利用索引。

关于MySQL GROUP BY 函数需要很多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47114556/

相关文章:

mysql - 按行合并两个mysql表

.net - 如何在不使用性能监视器的情况下以编程方式确定硬盘事件

php - 使用 +1 | 增加包含文本 + 数字的 DB 值 | WordPress的

mysql - 设计一个包含用户之间关系的表的好方法是什么?

performance - 如何测量 F# 代码的 CPU 和内存使用情况?

jquery - 如何测试图像是否已在缓存中?

r - 在自定义 R 函数中预分配内存以提高性能(使用 dplyr)

ios - react native 构建错误 : Could not read optimization profile file (even after change optimization configuration)

php - 编辑值在 php 中无法正常工作

python - 检查列表中是否存在子列表的最有效方法,忽略最后一个元素