Let's begin!
BAD/SLOW:
It's tempting to use a subquery inside an IN(...) list, but your query speed will slow exponentially as more rows are added. Don't be tricked by query caching either, since every new INSERT will erase the cache. The solution is to use an INNER JOIN and subquery instead.
GOOD/OPTIMIZED:
The UPDATE command allows you to join other tables. We can use a subquery on the same table to calculate new field values, then join this subquery as a "table."
For this example, a table contains a date field with values two weeks apart, but we want to change them to one week apart. (A user-defined variable @row is needed to keep track of the row number in order to calculate the new date.)
The keyword for performance is "caching." By taking the load off the processor and database, a website can easily handle hundreds of thousands of visitors. Many frameworks offers some sort of caching method that stores the final rendered HTML. This is easy to implement for anonymous users, but what about logged-in users?
I recently released an open-source Drupal module called Authenticated User Page Caching (Authcache) (and a demo site) for logged-in users. Drupal is a great PHP/MySQL CMS/framework for building community-based websites, though it suffers from a "one-more-query" syndrome--a single page request can have hundreds of SQL queries! The reason why authenticated caching is difficult is because most of the time, when you're logged into a website, the content changes according to your account (like a "You're logged in as [username]" link), so it's pointless to save the final HTML to the server's cache. Instead the entire page has to be rendered by PHP on each request, requiring precious CPU cycles & database hits. Ajax/JavaScript can be used for customizing the cached HTML, however. Of course, this technique can't be used with every website--some sites are just too dynamic--but it can work if the content of pages is similar across users.
Every millisecond counts when it comes to performing page requests--not only are cached pages served faster to the user, but it frees up services/memory faster on the server, giving more bang for your buck. This is important not only on high-volume websites, but when you're on a hosting plan that doesn't give you gig upon gigs of memory or high-performance CPU processing power.
The modular nature of Drupal and its excellent API makes it rather straightforward to implement this type of caching. Other frameworks may prove more difficult. The Authcache module can use a number of different caching engines, such as APC, memcached, or even static files. I've found that APC offers the fastest retrieval times, allowing pages to be served in under 1 millisecond!
Implementing Page Caching
The tricky part with page caching is knowing when to retrieve from the cache and when to delete outdated cache. If there is a POST request, such as when a comment is made, then Drupal/PHP will execute the page code normally and invalidate the cache. When we are logged in as an admin, we don't display or save cache pages (because we want our admin links and don't want users to see them). We may also expire our cache after a certain amount of time to always display the most up-to-date content, which is useful on a front page and search result page. Yes, these little details can be a hassle, but the end result is well worth it if your goal is a faster site.
What About Dynamic Content?
This is where the beauty of Ajax/JavaScript comes in. We don't need to re-render an entire page, just perform a separate confined action. For example, instead of having PHP render "Hello, [username]" text for each page for logged in users along with everything, store the username in a cookie and have JavaScript render the username. Then create a separate cache for pages for logged in users and one for anonymous users. If certain pages absolutely must be dynamic, then they can be excluded from the cache. Another example: I like to keep a view tally on my articles in this Wordpress blog. All my pages are cached, however, so to update the count my pages ping a small PHP script after loading, which checks the user's cookie to see if the article has been viewed, and if not, then it quickly connects to the database, sends an update query, then exits, all independently of the what matters the most: serving the page to the user.
Caching Tricks
There are also several browser caching techniques that can be used when cached HTML:
header("HTTP/1.1 304 Not Modified"); A 304 response does not send any HTML.) This saves on bandwidth and allows the browser to display the page directly from memory without having to redownload and parse the HTML again.
header("Cache-Control: max-age=3600, must-revalidate");). We can this header to cache Ajax responses. This is useful for blocks of user-specific content. For example, if a user votes on a poll, we would want to display the poll results and not the poll vote form. But we don't want to retrieve the poll results on each page view, so we can tell the browser to just cache the block for 10 minutes. A cookie with a timestamp can be used for cache invalidation (e.g., if a user changes their vote, a "vote" cookie containing the unix timestamp is saved, then the Ajax request uses this cookie value when generating the request URL).
Installing Cygwin
(You can skip this if you're backing up on a Linux machine.)
The first task is installing Cygwin on your Windows box, which provides a Linux-like environment for running our backup tools (rsync+ssh and cron). When running setup.exe, you should select as many packages as you feel comfortable installing by clicking
. Be sure to install all of "Admin," "Base," "Devel," and "Net." You can always run setup.exe later to update your existing Cygwin installation.
Creating SSH Public/Private Keys
Since we want to copy our files securely over SSH without being prompted for a password each time we login, we need to generate a public key for our backup machine. At the shell prompt, enter:
Ignore the questions by pressing "Enter" at any prompts, such as the file location or passphrase. Now open ~/.ssh/id_dsa.pub (e.g., c:/cgwin/home/(Windows Username)/.ssh/id_dsa.pub) file and copy the contents. Log in to your remote/Linux machine and paste this info into the file ~/.ssh/authorized_keys. If the file doesn't exist, just create a new one. You must also modify your SSH daemon to use allow Pubkey authentications. Edit /etc/ssh/sshd_config and uncomment:
On your backup machine, test your pubkey by typing (replacing username and remotehost):
You should now be able to login into your Linux server without typing in a password!
The rsync Backup Script
In other words, rsync is one of the best backup tools available.
Create your backup directory:
And create your backup script inside it, named backup.sh, making sure to replace username@localhost:
/var/www/ is the full path on the remote machine. /rsync/www/ is where to save on your backup machine. If you use a non-standard SSH port, you can use "ssh -p portNum" in quotes.
You can also backup your MySQL database files, log files, code repositories, or whatever else you desire. If you don't have access to the MySQL files directory, you can setup a mysqldump script on the remote machine to save to a file.
You may also want to create "snapshots" of your backups, so these files don't get overwritten by unwanted changes. Here's a snapshot script (snapshot.sh) that gzips MySQL database files:
Cygwin: Installing the "cron" service
Crontabs are used for automating our backup scripts. On Cygwin, cron must be setup as a Windows service in order to run in the background:
To see if the cron service is running, type:
Adding the Crontab:
On your backup server, type:
Press "i" and add:
Press "ESC" then "w" and enter to save.
This will run the backup script at midnight every day. You can also add a line for the snapshot.sh script... replace the first "0" with "30" to run the script 30 minutes later.
That's it! Now just make sure your backup server has your hard drives in a RAID 1 (mirroring) or better configuration for additional data redundancy!
]]><style> tags. For this reason, use inline CSS. Also, using tables to build your newsletters is a safe idea as well, since the float property isn't always supported. Outlook 2007 is extremely limited when rendering HTML--no background CSS images, no forms, no custom bullet images.
mail() function – This function opens and closes a connection to your mail server every time, which is extremely inefficient. It is possible to write your own bulk email sender in PHP, however! Use an SMTP class for more control and speed.
Received-SPF: neutral or Received-SPF: fail. It should only take 5 minutes to set this up and make it say "pass." For example, my domain register allows me to add DNS TXT records, so for the host field I would type "httpremix.com." and for the address field I would add "v=spf1 a mx -all" (quotes included for the TXT).
FIELD() function comes in handy.
The disadvantage is that this will slow down your query. For maximum performance, store the field as an ENUM with the values defined in the correct order.
Scenario: We have multiple values spread out across rows a table, but need to retrieve them together in a single field without performing multiple queries. I'm doing this for my archive page--I want to retrieve a list of topic tags for each article, but I want to do it with the same query that selects all my articles. GROUP_CONCAT() is the answer for string concatenation.
The "topic" column could then return values such as "php,mysql,css".
Here's a quick way to pick out that string:
]]>
<link rel="stylesheet" type="text/css" href="print.css" media="print" /> directive, however, it's better to place your print CSS within your main CSS file. Instead of having a separate CSS file for printing (which can increase the initial load time since the browser must make an additional HTTP request to the server before rendering the page), place @media print {... } at the bottom of your CSS file. It must be at the bottom to override your previous declarations.
]]>
First, let's take a look at a design element that every website has: the navigation menu.
And the ugly CSS:
There are several things that bug me about the above code:
<ul><li>)<ul> and <li> elements display (e.g.: How to Style Perfect HTML Lists) but didn't "reset" the list in our CSS? (Did you catch how ul.navMain li { ... } is missing margin: 0?) Less code is always better!id="idName") and class selector (class="className") have almost the exact same functionality. The general rule of thumb is that if your element/style only appears once on your page, use an id selector. Otherwise, use a class. Multiple classes may also be used within a single element (class="className1 className2 className3"), while id selectors cannot because they're designed to only be used once as a way to identify an unique element.The advantage is that a shorter document is created: less scrolling is involved making it much easier to pick out elements. Quicker changes = more efficiency = time saved. And it's not like single-line CSS looks horribly messy--it's incredibly easy to know what's going on with a single glance. We can look at any random line in a CSS file and know exactly where we are within the document, and that's beauty.
Does less vertical scrolling equal more horizontal scrolling? Not necessarily. When making updates, there are certain properties we're just not going to change, like display or float or even width. We put these at the very end of the line. color and font properties are nice to have up front (as clients love to play with these). We can also group similar attributes together, which we should be doing anyway, or use shorthand CSS (e.g., background:#000 url(../img/scan_lines.gif) repeat-y; margin:10px 20px; etc.). And with widescreen monitors becoming more prevalent, this leaves developers with more horizontal real estate that should be put to use.
Now there are several arguments against that I can understand: you use/need a special third-party tool to help you write CSS; you have word-wrapped turned on; you like to validate your CSS and want an exact line; or you are working with single-line haters. Otherwise, it's not "personal preference" when there is an obvious benefit to writing CSS using single lines. It took me a couple years before I switched over, but once I did I've never looked back.
The above CSS, rewritten:
I'd rather look at 4 lines of CSS than 29 lines any day of the week.
]]>
Do not use list-style-image! This property is not cross-browser friendly and has alignment issues. Take a look below:

Firefox aligns the bullets too south, while IE7 aligns them too north, and neither is centered. WTF?!! The alternative is "background," which gives us more control and predictability.
If you just want to remove the left margin and add padding between list items instead using a customized bullet image, less code is needed:
]]>
]]>