Closed (fixed)
Project:
Drupal core
Version:
x.y.z
Component:
base system
Priority:
Normal
Category:
Bug report
Assigned:
Reporter:
Created:
22 Dec 2005 at 20:44 UTC
Updated:
14 Jan 2006 at 12:01 UTC
Jump to comment: Most recent file
The SQL query used to populate a session is
db_query_range("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = '%s' AND u.status < 3", $key, 0, 1);
To my knowledge we never use a value for u.status other than 0 (blocked) and 1 (allowed). Because the AND clause will always be true, this patch eliminates that clause, thus speeding up the database call.
| Comment | File | Size | Author |
|---|---|---|---|
| #20 | user_48.patch | 2.43 KB | m3avrck |
| #5 | drupal_29.patch | 2.14 KB | m3avrck |
| #4 | drupal_28.patch | 1.88 KB | m3avrck |
| #2 | drupal_27.patch | 1.89 KB | m3avrck |
| fastersession.patch | 994 bytes | jvandyk |
Comments
Comment #1
m3avrck commentedThis patch should be extension to fix user_load() where dynamic queries look like:
SELECT u.* FROM users u WHERE u.uid = 0 AND LOWER(u.status) = LOWER('1') AND u.status < 3 LIMIT 0, 1Seems to be very related queries which would boost things up a bit indeed.
Comment #2
m3avrck commentedAbove patch doesn't apply to CVS :-)
Here's a new patch that applies and also fixes the only other u.status < 3 query that I could find in core. Both should be eliminated now and minor performance improvements as a result.
Comment #3
m3avrck commentedBy the way, that dynamic query above now is:
SELECT u.* FROM users u WHERE u.uid = '1' AND u.status = '1' AND 11 is needed because various parameters in there, not consistent, only way to always work.
Comment #4
m3avrck commentedHere's an even better patch, we don't need the slower db_range in there anymore either.
Comment #5
m3avrck commentedOk even better patch, using implode thanks to killes suggestion to further simplify things.
Comment #6
killes@www.drop.org commentedlooks much nocer now. i am still wondering why we had the LOWER and the db_query_range there in the first place, though.
Comment #7
m3avrck commentedYeah I was scratching my head about that but I see no reason for it to be used, my best guess is that it was some legacy code that just was never really ever updated, I'm going to set this to commit then, Dries, I'm sure you'll be able to enlighten us on that db_range() stuff. :-)
Comment #8
Cvbge commentedI guess this LOWER() stuff was because the author wanted to match some fields ignoring case. You could use it for matching e.g. mail (the local [account] part *can* be case-sensitive, but usually isn't, so it'd be good to compare it case-insensitive) or other text columns (themes, signature, language and others)
Correct sollution would be not to build the query autmatically, but explicitly using column names.
Comment #9
m3avrck commentedThis does not make any sense, the query needs to be made dynamically, if you take a look at all of the user_load() calls in user.module, you'll see that they each pass in various paramaters at various times (uid, status, etc...) no way to *not* build this dynamically. This patch also *isnt* changing anything, it is merely simplifying things and possibly introducing some small performance tweaks (simpler queries).
Comment #10
Cvbge commentedThis does make a lot of sense, the query does not need to be made dynamically, if you take look at the user_load() definition you'll see that it uses the parameters with {user} only so we know what columns are possibile (uid, status, etc...) so there *is* a way to build this dynamically. The patch is also removing LOWER() form values which can change the behaviour.
Comment #11
Cvbge commentedOf course I meant "to build this not dinamically".
Comment #12
moshe weitzman commentedcode looks good to me.
Comment #13
moshe weitzman commentedcode looks good to me.
Comment #14
dries commentedCvbge: are you saying this should be committed as is, or not? Did you test this patch on PostgreSQL? Is using '%s' for integers a problem?
Comment #15
dries commentedAs for the db_query_range(); I vaguely remember that sessions.sid wasn't always a unique or primary key.
I'll commit this patch as soon Cvbge is happy with it. :-)
Comment #16
chx commentedDries, I do remember that sessions sid IS a unique key and before we made it primary key, we inspected Drupal.org database and it had VERY few number of duplicate sids which we deemed as error.
Comment #17
Cvbge commentedWhat I ment is that this patch changes the user_load() behaviour.
Currently the values are lowecased, so e.g.
user_load(array('mail' => 'Joe@Doe.com'))will load user with mailJoe@doe.com, but after this patch it won't do that.This could create problems.
Or course, the questions is, do we want to lowercase all, or some values? If yes, or if we want to do it as it's done now, we should change the patch.
Comment #18
Cvbge commentedI don't have other problems with this patch.
Comment #19
m3avrck commentedCvbge, ok I understand what you are saying now. I just checked core, we have 9 out of 40 calls to user_load() that use a string: name or mail, which *might* need the lower(). Ok, I have a new idea for a patch that should fix this and still simplify things...
Comment #20
m3avrck commentedOk here we go, an updated query that still leaves the LOWER() in there but changes up the logic a bit. Since a majority of the calls to user_load() are based on uid or status, I put these as the first checks in the if/else bracket since this will save time parsing through the others. Since there are only a few calls to name and mail, this is the last check and LOWER() is used on these and all others, assuming any other calls to user_load() might be calling fields that need this.
Overall, this patch should be solid now and ready to commit, so someone please review and set the status as needed!
Comment #21
Cvbge commentedok with me.
Applied to local test site, clicked here and there, created user, logged in/out, haven't seen any problems.
BTW, wouldn't db_query_range() be faster, or at least as fast as db_query()? Just wondering, really ;)
Comment #22
Cvbge commentedAn after-note, just to educate people ;)
yes, it can be. If you pass a NULL or FALSE to '%s' it'll be changed to ''. This value will be inserted into mysql and automagically changed to 0 (or default value, don't remember). But it will produce error for postgresql.
So it's better to use %d, NULL/FALSE will be changed to 0 in both mysql and postgresql.
Comment #23
dries commentedCommitted. Good catch, good work. Thanks guys.
Comment #24
(not verified) commented