【发布时间】:2020-12-04 09:19:29
【问题描述】:
我正在使用 Django 3、Python 3.8 和 MySql 8。我有以下 Django 模型,我在其中创建基于部分名称的搜索...
class Coop(models.Model):
objects = CoopManager()
name = models.CharField(max_length=250, null=False)
types = models.ManyToManyField(CoopType, blank=False)
addresses = models.ManyToManyField(Address)
enabled = models.BooleanField(default=True, null=False)
phone = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_phone')
email = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_email')
web_site = models.TextField()
...
# Look up coops by a partial name (case insensitive)
def find_by_name(self, partial_name):
queryset = Coop.objects.filter(name__icontains=partial_name, enabled=True)
print(queryset.query)
return queryset
上面的代码产生了这个查询...
SELECT `directory_coop`.`id`, `directory_coop`.`name`, `directory_coop`.`enabled`, `directory_coop`.`phone_id`, `directory_coop`.`email_id`, `directory_coop`.`web_site` FROM `directory_coop` WHERE (`directory_coop`.`enabled` = True AND `directory_coop`.`name` LIKE %Credit%)
下面是 Django 迁移生成的表。我可以进行任何类型的索引或其他调整来加快这些查询 - 具体来说,“name LIKE %Credit%”部分?
CREATE TABLE `directory_coop` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL,
`enabled` tinyint(1) NOT NULL,
`phone_id` int DEFAULT NULL,
`email_id` int DEFAULT NULL,
`web_site` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `directory_coop_email_id_c20abcd2` (`email_id`),
KEY `directory_coop_phone_id_4c7e2178` (`phone_id`),
CONSTRAINT `directory_coop_email_id_c20abcd2_fk_directory_contactmethod_id` FOREIGN KEY (`email_id`) REFERENCES `directory_contactmethod` (`id`),
CONSTRAINT `directory_coop_phone_id_4c7e2178_fk_directory_contactmethod_id` FOREIGN KEY (`phone_id`) REFERENCES `directory_contactmethod` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=993 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
【问题讨论】:
-
您可以通过在特定字段中添加
pk=True来设置模型中的主键。你也可以设置db_index(在这里阅读docs.djangoproject.com/en/3.1/ref/models/fields/#db-index),但总的来说,如果你知道自己在做什么并且ORM不能满足你的需求,我建议跳过ORM并编写原始查询......跨度> -
@ArakkalAbu,接受的答案是“全文搜索可用于 MySQL 5.6+ 的 InnoDB 表。”但它并没有提供很多其他细节。你说的是这个吗?
-
在这方面,我想指出两点,1)。新的 MySQL 版本支持full-text search,可以在您的情况下使用custom database function。 2.) 索引不会加速
LIKE查询,它解决了您提出的确切问题。 -
那么你是说即使我将列类型更改为“FULLTEXTSEARCH”,也不会加快 LIKE 查询的速度?
标签: python-3.x django indexing sql-like mysql-8.0