views:

70

answers:

2

I want to check for the username in the users table.
If it's found, then I want to get the id.
Otherwise, I want to insert the username as a new record, then get the id.
Here's my code:

<?PHP
$sql = "SELECT id FROM users where username = '$username'";
$query = mysql_query($sql) or die(mysql_error());
$result = mysql_num_rows($query);
if($result){
    $row = mysql_fetch_array($query);
    $userid = $row["id"];
}else{
    $sql = "insert into users set username = '$username'";
    $query = mysql_query($sql) or die(mysql_error());
    $userid = mysql_insert_id();
}
?>

How can I optimize or combine these MySQL queries?

Can I select and insert in the same query?

and would it be better and faster?

+1  A: 

If you want this to be fast make sure you index username.

DigitalRoss
A: 

It's better to INSERT first, with the assumption that the username does not exist. If any error is caused by a duplicate conflict, SELECT the existing row.

<?php
$sql = "INSERT INTO users SET username = '" 
  . mysql_real_escape_string($username) . "'";
$query = mysql_query($sql);
if ($query === true) {
    $userid = mysql_insert_id();
} else {
    if (mysql_errno() != 1022) { // this is the duplicate key error code
        die(mysql_error());
    }
    $sql = "SELECT id FROM users where username = '"
      . mysql_real_escape_string($username) . "'";
    $query = mysql_query($sql) or die(mysql_error());
    $row = mysql_fetch_array($query);
    if ($row !== false) {
        $userid = $row["id"];
    }
}
?>

The reason this is better is that if you select then insert, someone else might insert the username in the moment between your two SQL statements.

Of course you should have a UNIQUE constraint on users.username.


Re your comment: yes, it should be faster that your script. When there is no duplicate username (which is probably more common), you don't have to run the SELECT.

The best way to optimize an SQL query is not to run it at all.

Bill Karwin
thanks, is it faster than my script?
ahmed