Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use force_index to exec update SQL #1025

Open
0RAJA opened this issue Jul 20, 2023 · 4 comments
Open

Can't use force_index to exec update SQL #1025

0RAJA opened this issue Jul 20, 2023 · 4 comments

Comments

@0RAJA
Copy link

0RAJA commented Jul 20, 2023

Python Version

3.10.11

Django Version

3.2.19

MariaDB/MySQL Version

Mysql 8.0.32

Package Version

4.11.0

Description

I hope to execute the "update" statement through "force_index", but the comment in the actual executed sql becomes "where 1", I'm not sure if this is normal behavior.
project settings

INSTALLED_APPS += (
    ...
    "django_mysql"
)
...
DJANGO_MYSQL_REWRITE_QUERIES = True
...
class OperateRecordQuerySet(QuerySetMixin):
    ...
class OperateRecordModel(models.Model):
    objects = OperateRecordModelManager().from_queryset(OperateRecordQuerySet)()

i try to use this orm code

class BusinessInfo(OperateRecordModel):
    combined_id = models.CharField(
        primary_key=True,
    )
...

delete_filter = {self.pk_field + "__in": delete_combined_ids}
BusinessInfo.model.objects.force_index("PRIMARY").filter(**delete_filter).update(is_deleted=True)

but I watch the original sql

from django.db import connection
queries = connection.queries
logger.info(queries)

this is the result

UPDATE `xxx` SET `is_deleted` = 1 WHERE ((1) AND `xxx`.`combined_id` IN ('xxx'))

for other index name,these sqls are same

I don't know if this is a normal result, please help me to confirm, thanks

@0RAJA 0RAJA changed the title can't use force_index to update sql can't use force_index to update Jul 21, 2023
@0RAJA 0RAJA changed the title can't use force_index to update Can't use force_index to exec update SQL Jul 21, 2023
@adamchainz
Copy link
Owner

The where 1 is normal behaviour, the way the SQL gets injected is a little weird.

Does UPDATE actually support query hints? If so we could add support, hopefully you'd be up for opening a PR.

@0RAJA
Copy link
Author

0RAJA commented Jul 24, 2023

Thanks for your response.

Index hints can indeed be used in update statements.
Here is the documentation..
And these are samples.

EXPLAIN UPDATE `sync_businessinfo`
SET `is_deleted` = 0,
    `updated_by` = NULL,
    `updated_at` = '2023-07-20 17:07:46.138592'
WHERE (`sync_businessinfo`.bk_biz_id IN (0));
image

when I use force index.

explain
UPDATE `sync_businessinfo` force index (`PRIMARY`)
SET `is_deleted` = 0,
    `updated_by` = NULL,
    `updated_at` = '2023-07-20 17:07:46.138592'
WHERE (`sync_businessinfo`.bk_biz_id IN (0));
image

I use force index in the update statement because the mysql optimizer will choose not to use the index when the update statement contains a large number of where statements, resulting in serious performance problems

I'm going to try to figure out how to implement force index for the update statement

@0RAJA
Copy link
Author

0RAJA commented Jul 24, 2023

I think the force index of the update statement cannot be realized through the extra provided by django orm, and it may need to be realized through raw sql

@adamchainz
Copy link
Owner

Raw SQL is not needed if we extend Django-MySQL’s feature. django_mysql.rewrite_query is where to make changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants