On Sat, Jul 19, 2008 at 4:18 AM, Rob Wultsch <[EMAIL PROTECTED]> wrote:
> On Fri, Jul 18, 2008 at 3:46 PM, Rob Wultsch <[EMAIL PROTECTED]> wrote:
>> I'm sure there is a way to write this in a single query, but I bet it
>> it is ugly as heck, probably with a bunch of derived tables.
>
> INSERT INTO balances (userid, points)
> SELECT users.userid, users.points
> FROM users
> LEFT JOIN (
> SELECT userid, MAX(timestamp_dump) AS 'timestamp_dump'
> FROM balances
> GROUP BY userid
> ) AS b1 USING(userid)
> LEFT JOIN balances b2 USING(userid,timestamp_dump)
> WHERE users.points != b2.points
> OR b2.points IS NULL ;
>
> This query is a dog, That stored procedure is pretty horrible. I'm
> going to play with trying to figure out how to optimize this. Fun
> stuff.
>
>
> --
> Rob Wultsch
>
Unless I am missing something Postgres is 100X faster for the query shown above.
Awesome...
postgres=# DROP TABLE IF EXISTS users, balances;
DROP TABLE
postgres=# CREATE TABLE users(
postgres(# userid SERIAL,
postgres(# points INT);
NOTICE: CREATE TABLE will create implicit sequence "users_userid_seq" for seria
l column "users.userid"
CREATE TABLE
postgres=# CREATE TABLE balances(
postgres(# userid INT,
postgres(# points INT,
postgres(# timestamp_dump TIMESTAMP DEFAULT NOW(),
postgres(# PRIMARY KEY(userid,timestamp_dump) );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "balances_pkey" f
or table "balances"
CREATE TABLE
postgres=# INSERT INTO users(points)
postgres-# SELECT random()*100 FROM generate_series(0,10000) ;
INSERT 0 10001
postgres=# INSERT INTO balances (userid, points)
postgres-# SELECT users.userid, users.points
postgres-# FROM users
postgres-# LEFT JOIN (
postgres(# SELECT userid, MAX(timestamp_dump) AS timestamp_dump
postgres(# FROM balances
postgres(# GROUP BY userid
postgres(# ) AS b1 USING(userid)
postgres-# LEFT JOIN balances b2 USING(userid,timestamp_dump)
postgres-# WHERE users.points != b2.points
postgres-# OR b2.points IS NULL ;
INSERT 0 10001
postgres=# UPDATE users
postgres-# SET points = random()*100
postgres-# WHERE random()< .3;
UPDATE 2976
postgres=# select now();
now
----------------------------
2008-07-19 06:26:31.359-07
(1 row)
postgres=# INSERT INTO balances (userid, points)
postgres-# SELECT users.userid, users.points
postgres-# FROM users
postgres-# LEFT JOIN (
postgres(# SELECT userid, MAX(timestamp_dump) AS timestamp_dump
postgres(# FROM balances
postgres(# GROUP BY userid
postgres(# ) AS b1 USING(userid)
postgres-# LEFT JOIN balances b2 USING(userid,timestamp_dump)
postgres-# WHERE users.points != b2.points
postgres-# OR b2.points IS NULL ;
INSERT 0 2946
postgres=# select now();
now
----------------------------
2008-07-19 06:26:31.593-07
(1 row)
mysql> DROP TABLE IF EXISTS users, balances, integers;
Query OK, 0 rows affected (0.41 sec)
mysql> CREATE TABLE users(
-> userid INT PRIMARY KEY AUTO_INCREMENT,
-> points INT);
Query OK, 0 rows affected (0.13 sec)
mysql> CREATE TABLE balances(
-> userid INT,
-> points INT,
-> timestamp_dump TIMESTAMP,
-> PRIMARY KEY(userid,timestamp_dump) );
Query OK, 0 rows affected (0.13 sec)
mysql> CREATE TABLE integers(i tinyint);
Query OK, 0 rows affected (0.11 sec)
mysql> INSERT INTO integers(i)
-> VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
Query OK, 10 rows affected (0.06 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> INSERT INTO users(points)
-> SELECT rand()*100
-> FROM integers AS i1,
-> integers AS i2,
-> integers AS i3,
-> integers AS i4
-> WHERE i1.i + i2.i *10 + i3.i * 100 + i4.i *1000 < 10000 ;
Query OK, 10000 rows affected (0.31 sec)
Records: 10000 Duplicates: 0 Warnings: 0
mysql> INSERT INTO balances (userid, points)
-> SELECT users.userid, users.points
-> FROM users
-> LEFT JOIN (
-> SELECT userid, MAX(timestamp_dump) AS 'timestamp_dump'
-> FROM balances
-> GROUP BY userid
-> ) AS b1 USING(userid)
-> LEFT JOIN balances b2 USING(userid,timestamp_dump)
-> WHERE users.points != b2.points
-> OR b2.points IS NULL ;
Query OK, 10000 rows affected (0.38 sec)
Records: 10000 Duplicates: 0 Warnings: 0
mysql> UPDATE users
-> SET points = rand()*100
-> WHERE rand()< .3;
Query OK, 2970 rows affected (0.16 sec)
Rows matched: 2990 Changed: 2970 Warnings: 0
mysql> INSERT INTO balances (userid, points)
-> SELECT users.userid, users.points
-> FROM users
-> LEFT JOIN (
-> SELECT userid, MAX(timestamp_dump) AS 'timestamp_dump'
-> FROM balances
-> GROUP BY userid
-> ) AS b1 USING(userid)
-> LEFT JOIN balances b2 USING(userid,timestamp_dump)
-> WHERE users.points != b2.points
-> OR b2.points IS NULL ;
Query OK, 2970 rows affected (20.05 sec)
Records: 2970 Duplicates: 0 Warnings: 0
--
Rob Wultsch
--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe: http://lists.mysql.com/[EMAIL PROTECTED]