简体   繁体   中英

MySQL SELECT from one table and INSERT in another - Performance

The situation is: In one http GET request I need to select from one table the information I need and send to the client, and at the same time I need to retrieve the user IP and insert into a database. I'm using Node.js for this experiment.

The thing is: Is there a way to make the two actions together? Or do I have to connect and make two separate queries? Is there a way to render the page and do the other INSERT action in the background? What is the fastest option?

app.get('/', function({
    connect.query("SELECT column1, column2 FROM table;", function(err, ... 
        render("index", ...);
    });

    connect.query("INSERT INTO table2 SET ip=11111111;");
});

You can make a stored procedure do this

Basically these are two different operations, but doing it in stored procedures might give you the assurance that it will surely happen, you can pass the IP address as the parameter into the stored procedure, this will also avoid any worries of performance in the code for you as the db takes care of insert, please remember that any select that does not insert into a table or a variable will produce a result set for you to use, hope this helps.

DELIMITER $
CREATE PROCEDURE AddIPandReturnInfo 
(
    @IPAddress varchar(20)
)
BEGIN
    INSERT INTO Yourtable (IPAddress);

    SELECT   *   FROM    Tablename;
END $
DELIMITER ;

The procedure approach suggested by @skv is nice but you have to wait for the write before doing the read and eventually returning a result to the user.

I would argue for another approach.

  • Queue the ip-address and a timestamp internally in something like an array or list.
  • Do the read from the database and return a result to the user
  • Create a background job that will nibble of the internal array and do the inserts

This has several benefits

  • The user gets a result faster
  • The writes can be done later if the system is being called in bursts
  • The writes can be done in batches of tens or hundreds of inserts reducing the time it takes to write one row.

Well, I assume you're using this module https://github.com/felixge/node-mysql

The MySQL protocol is sequential , then, to execute paralell queries against mysql, you need multiple connections. You can use a Pool to manage the connections.(builtin in the module)

Example:

var mysql = require('mysql');
var pool = mysql.createPool({
    host: 'example.org',
    user: 'bob',
    password: 'secret',
    connectionLimit: 5 // maximum number of connections to create at once **10 by default**
});
app.get('/', function (req, res) {
    // get a connection from the pool //async
    pool.getConnection(function (err, connection) {
        // Use the connection
        connection.query('SELECT something FROM table1', function (err, rows) {
            // Do somethig whith the mysql_response and end the client_response
            res.render("index", {...
            });
            connection.release();
            // Don't use the connection here, it has been closed.
        });
    });
    //async
    var userIp = req.connection.remoteAddress || req.headers['x-forwarded-for'] || null;
    if (userIp) {
        // get a connection from the pool again
        pool.getConnection(function (err, connection) {
            // Use the connection
            connection.query('INSERT INTO table2 SET ip=?', [userIp], function (err, rows) {
                // And done with the insert.
                connection.release(); // Conn Close.
            });
        });
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM