-3

I'm experiencing a performance issue with MySQL when deploying my application to a live server. The problem occurs when creating a short link for the first time after a period of inactivity. Specifically, the initial query to the database takes a long time to execute, but subsequent queries perform normally.

Context I have a Node.js application using mysql2 with a connection pool. The application is deployed on Render, and the MySQL database is hosted on Clever Cloud. Here is how I've set up the connection and the controller function for creating short links:

Database Connection Configuration (config/db_connection.js):

const mysql = require('mysql2');

const pool = mysql.createPool({
    host: process.env.DB_HOST,
    user: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    waitForConnections: true,
    connectionLimit: 10, // Adjust the limit based on your requirements
    queueLimit: 0
});

module.exports = pool.promise(); // Using promise-based pool for async/await
Controller Function for Creating Short Links (controllers/createLinkController.js):


const pool = require("../../config/db_connection");
const ShortUniqueId = require('short-unique-id');

const createLink = async (req, res, next) => {
let { original_url, userId, shortened_url } = req.body;

const uid = new ShortUniqueId();
const user_id = userId || process.env.DEFAULT_USER_ID;
const trackingId = uid.randomUUID(10);

const checkAndInsertLink = async () => {
    if (!shortened_url) {
        shortened_url = uid.randomUUID(6);
    }

    const insertQuery = `INSERT INTO links (user_id, original_url, shortened_url, tracking_id) VALUES (?, ?, ?, ?)`;
    try {
        await pool.query(insertQuery, [user_id, original_url, shortened_url, trackingId]);
        res.status(201).json({ shortened_url: `https://qct.netlify.app/${shortened_url}`, trackingId });
    } catch (error) {
        console.error('Error inserting link:', error);
        res.status(500).json({ error: 'Internal server error 1' });
    }
};

if (shortened_url) {
    const checkQuery = `SELECT * FROM links WHERE shortened_url = ?`;
    try {
        const [results] = await pool.query(checkQuery, [shortened_url]);
        if (results.length !== 0) {
            res.status(409).json({ message: "Link already exists" });
            } else {
                checkAndInsertLink();
            }
        } catch (error) {
            console.error('Error checking link:', error);
            res.status(500).json({ error: 'Internal Server error 2' });
        }
    }  else {
        checkAndInsertLink();
    }
};

module.exports = createLink;

My database structure:

CREATE TABLE links (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
original_url VARCHAR(2048) NOT NULL,
shortened_url VARCHAR(100) NOT NULL UNIQUE,
tracking_id VARCHAR(255) NOT NULL,
clicks INT DEFAULT 0,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE 
CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES userList(id)
);
ALTER TABLE links
ADD INDEX idx_tracking_id (tracking_id);
CREATE TABLE link_tracking (
id INT PRIMARY KEY AUTO_INCREMENT,
tracking_id VARCHAR(100),
ip_address VARCHAR(100),
country VARCHAR(100),
city VARCHAR(100),
user_agent VARCHAR(2000),
browser VARCHAR(100),
os VARCHAR(100),
battery_status VARCHAR(100),
opened_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (tracking_id) REFERENCES links(tracking_id)
);

Issue When creating a short link for the first time after a long period of inactivity, the query to create the link is unusually slow. After the initial slow query, subsequent queries execute normally without delay.

Environment Deployment Platform: Render Database Host: Clever Cloud Questions Why might the initial query be slow after a period of inactivity? Are there any specific settings or configurations I should check on Clever Cloud or Render that might affect performance? What can be done to improve the performance of the initial query? Any insights or suggestions would be greatly appreciated. Thank you!

5
  • 1
    Is there an index in the shortened link column? Commented Jul 11, 2024 at 13:03
  • Why might the initial query be slow after a period of inactivity? Cold cache immediately comes to mind, while subsequent queries fetch from the cached data, it affects all queries, specially those unindexed where large amounts of data needs to be read. Commented Jul 11, 2024 at 13:04
  • i am having two table one for storing links and another for storing details of who has open the links. for each row i am having tracking Id which is a foreign key for link_tracking. I have only index on tracking_id Commented Jul 11, 2024 at 13:13
  • Post the full query you're using, along with table structure and existing indexes. The result of query explain can be useful too. Commented Jul 11, 2024 at 13:16
  • I have edited my questions to add the query by which i create the database Commented Jul 11, 2024 at 13:31

1 Answer 1

0

Caching.

After a backup or a table scan the cache may be flushed, making subsequent queries slow.

For further discussion, please provide

  • amount of RAM
  • SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
  • The slow query.
  • EXPLAIN SELECT ... -- of the slow query.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.