The battle of SQL query performance on large systems

My sleep was rudely interrupted yesterday morning at 9am (yes, 9am). It was Brian calling to tell me that the new database server we setup for calendars had a load of about 22 — ridiculous. I threw on some clothes, pulled Kevin out of kindergarten orientation, and headed into the office to see what was up. This is what we all found out:

We have a reminder query that uses a subquery compared against an indexed field on the table. This never used to cause problems, but something changed from MySQL 4 to 5 that caused the query to take .08 seconds. When we found out how long it took, Brian literally said, “See, it’s only .08 seconds. That shouldn’t cause problems.” But it did…

We have thousands of users hitting this query around the same time. Combine that with all of the other normal traffic, and the server just can’t catch up. We discovered what was wrong by using EXPLAIN, and found out it was scanning about 2,000 rows on average. We switched the query to use JOINs instead and got the number of rows scanned down to about 15.

I’ve since decided to start a campaign to run EXPLAIN on every query we use to make sure things are running as efficiently as possible. You should do the same.

The biggest lesson we learned is that just because something seems to be fast by itself, doesn’t mean it performs well. My next post will tell you about my second crisis of yesterday that reinforces this lesson, unfortunately.

April 24th, 2007 · Tags Development, MySQL, Performance | Comments Off

Deleting element properties in Internet Explorer

We have a widget system on the frontend of webmail that allows us to use a factory() method and a destroy() method to avoid memory leaks. I recently wrote a Menu widget that saves data about each item in a property on the element called “_item”. Since this is a custom property I don’t need to keep it once the menu is hidden, I want to remove it for memory leak purposes.

The following code works like a charm:

delete element._item;

Except in Internet Explorer. Apparently IE doesn’t like people deleting properties off of elements. So I came up with this solution:

try {
    delete element._item;
} catch (e) {
    element.removeAttribute('_item');
}

This works great without erroring, but I don’t know if it actually has the same memory implications. Does anyone know?

April 12th, 2007 · Tags Javascript, Development, Internet Explorer | 1 Comment »

Firefox Parser object

Today Nithiwat called me over to help him figure out why his Parser object wouldn’t load via our wm_require() function which loads javascript on-demand if the object is not found. We figured out the problem fairly quickly, but learned one very important lesson: Prefix all global objects with something you know no one else will use.

Apparently in Firefox there is a native Parser object (which I can’t find a reference for). In the past, we loaded our Parser.js file with no problem, as it simply overwrote the native object. Obviously that doesn’t work anymore. So it’s going in our newly formed wack library.

I can’t wait to tell people what that stands for…

April 10th, 2007 · Tags Javascript, Development, Firefox | Comments Off

Safari: eval() in global scope

We recently converted webmail’s javascript handling to an on-demand system to allow for faster login experience. The trickiest part about this was figuring out a cross-browser solution for eval’ing downloaded code in a global scope synchronously (Async is fairly easy using setTimeout and such, but that doesn’t work for us).

Google got me pretty far, with the exception of Safari. I found a few examples that dynamically created a script tag and put the code on the .text property, but that didn’t do anything when I tried it. So I tried using the .innerHTML property instead, but that gave me parse errors.

Then I got it … use the above approach, but use an eval inside to execute the code.

window.my_code = "var x = 3;" //code being in a variable is important
var script_tag = document.createElement('script');
script_tag.type = 'text/javascript';
script_tag.innerHTML = 'eval(window.my_code)';
document.getElementsByTagName('head')[0].appendChild(script_tag)
alert(window.x);

Works like a charm.

Note: This only works in Safari. Firefox runs the eval, but does not wait for it to finish before continuing.

March 17th, 2007 · Tags Javascript, Development, Safari | Comments Off