繁体   English   中英

如何提高mysql查询性能?

[英]How to improve mysql query performance?

我在rental_schedules 表中有大约400 万条记录和大约1k 前提,获取数据最多需要1.5 秒。 现在是时候了,或者我可以以某种方式优化更多? 这是我的查询:

select
  count(*) as aggregate
from
  `premises`
where
  exists (
    select
      *
    from
      `rental_schedules`
    where
      `premises`.`id` = `rental_schedules`.`premises_id`
      and `date` >= '2021-07-01'
      and `public_enterprise` = 0
      and `rental_schedule_status` = 1
  )
  and exists (
    select
      id
    from
      rental_schedules
    where
      premises.id = rental_schedules.premises_id
      and public = 1
      and public_enterprise = 0
  )

这是我的前提表索引:

  PRIMARY KEY (`id`),
  KEY `premises_institution_id_foreign` (`institution_id`),
  KEY `premises_responsible_user_id_foreign` (`responsible_user_id`),
  KEY `premises_cover_type_id_foreign` (`cover_type_id`),
  KEY `premises_premises_type_id_foreign` (`premises_type_id`),
  CONSTRAINT `premises_cover_type_id_foreign` FOREIGN KEY (`cover_type_id`) REFERENCES `cover_types` (`id`),
  CONSTRAINT `premises_institution_id_foreign` FOREIGN KEY (`institution_id`) REFERENCES `institutions` (`id`) ON DELETE CASCADE,
  CONSTRAINT `premises_premises_type_id_foreign` FOREIGN KEY (`premises_type_id`) REFERENCES `premises_types` (`id`),
  CONSTRAINT `premises_responsible_user_id_foreign` FOREIGN KEY (`responsible_user_id`) REFERENCES `dashboard_users` (`id`)

这是我的租赁时间表表索引:

  PRIMARY KEY (`id`),
  KEY `rental_schedules_date_index` (`date`),
  KEY `rental_schedules_week_day_id_foreign` (`week_day_id`),
  KEY `rental_schedules_rental_schedule_status_foreign` (`rental_schedule_status`),
  KEY `rental_schedules_contract_id_foreign` (`contract_id`),
  KEY `rental_schedules_bill_id_foreign` (`bill_id`),
  KEY `rental_schedules_accordion_id_index` (`accordion_id`),
  KEY `premises_search` (`premises_id`,`rental_schedule_status`,`date`,`public_enterprise`),
  KEY `rental_schedules_search` (`premises_id`,`public`,`public_enterprise`,`rental_schedule_status`),
  KEY `rental_schedules_search_with_date` (`premises_id`,`public`,`public_enterprise`,`rental_schedule_status`,`date`),
  CONSTRAINT `rental_schedules_bill_id_foreign` FOREIGN KEY (`bill_id`) REFERENCES `bills` (`id`) ON DELETE SET NULL,
  CONSTRAINT `rental_schedules_contract_id_foreign` FOREIGN KEY (`contract_id`) REFERENCES `contracts` (`id`) ON DELETE SET NULL,
  CONSTRAINT `rental_schedules_premises_id_foreign` FOREIGN KEY (`premises_id`) REFERENCES `premises` (`id`),
  CONSTRAINT `rental_schedules_rental_schedule_status_foreign` FOREIGN KEY (`rental_schedule_status`) REFERENCES `rental_schedule_statuses` (`id`),
  CONSTRAINT `rental_schedules_week_day_id_foreign` FOREIGN KEY (`week_day_id`) REFERENCES `week_days` (`id`)

提前感谢您的帮助!

我可能忽略了它,但我认为您在这里不需要 2 个不同的 EXISTS 运算符。 因此您的查询可以优化为 -

select count(*) as aggregate
  from `premises`
 where exists (select null
                 from `rental_schedules`
                where `premises`.`id` = `rental_schedules`.`premises_id`
                  and `date` >= '2021-07-01'
                  and `public_enterprise` = 0
                  and `rental_schedule_status` = 1
                  and public = 1);
SELECT COUNT(*) AS aggregate
    FROM premises AS p
    JOIN rental_schedules AS rs  ON p.`id` = rs.`premises_id`
    WHERE `date` >= '2021-07-01'
      AND `public_enterprise` = 0
      AND `rental_schedule_status` = 1
      AND public = 1;

rental_schedules上的“复合”和“覆盖”索引将有助于:

INDEX(public_enterprise, rental_schedule_status, public, date, premises_id)

列的顺序很重要 -- =首先,然后范围>= ,然后完成“覆盖”所需的任何其他内容。

如果所有这些 id 都是BIGINT ,请注意每个都需要 8 个字节,并且大小可能有点过大。

暂无
暂无

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

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