Opened 17 years ago
Closed 17 years ago
#5030 closed (fixed)
Remove COUNT(*) aggregate from model.save() when determining whether row exists
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | model save | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Currently, the save method of the Model object uses an aggregate function to determine if a row with the specified primary key already exists. However, we don't need to know the count just whether the row exists or not. An alternative is to just simply SELECT 1 so if the row exists it will return 1, and if not we get a null. On PostgreSQL the COUNT(*) version takes over twice as long as the SELECT 1 version (it's not that significant but it is unnecessary work). Patch attached.
Attachments (1)
Change History (10)
by , 17 years ago
Attachment: | aggregateDiff.diff added |
---|
comment:1 by , 17 years ago
Are you peeking over my shoulder or something? I *just* noticed this literally 5 minutes ago, when I was snooping around in base.py
. Wow.
Yes, we should make this change.
comment:3 by , 17 years ago
Triage Stage: | Unreviewed → Accepted |
---|
Promoting to accepted because Adrian was obviously too shocked to do that himself. Just wanted to check, COUNT 1
works across all supported databases?
comment:4 by , 17 years ago
The patch looks perfect, but I'm not in a position to test it against any database other than Postgres. Can somebody test this against all the other DBs?
comment:5 by , 17 years ago
I've run the django test suite over both Sqlite and Postgres and all tests passed. However, I can't test MySQL, SQL Server or Oracle myself.
comment:6 by , 17 years ago
I ran the tests with a MySQL database against r5783. One test failed with and without the patch.
So the patch seems to work fine with MySQL.
comment:8 by , 17 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Commenters to the above thread show that the SELECT 1 does work on Oracle and SQL Server and is more efficient. I've check the explain plans under SQlite and MySQL (both InnoDB and MyISAM tables) and SELECT 1 is more efficient on SQLite and exactly the same in MySQL.
comment:9 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Patch