【问题标题】:How to properly page data from SQL database?如何正确分页 SQL 数据库中的数据?
【发布时间】:2020-07-15 12:19:47
【问题描述】:

我想问一个关于如何正确分页 MySQL 数据库中的数据的问题。简单来说,我有一个包含相当多记录的数据库,我试图分页的这个特定表有 400-500 行。我确实想问什么是最好的方法,就分页这些数据的速度和内存成本而言?

我目前的解决方案和控制器:

[HttpGet("{startIndex}")]
public IEnumerable < ServerList > Get(int startIndex) {
    Console.WriteLine(startIndex);
    List < ServerList > serverList = new List < ServerList > ();
    string constr = _configuration.GetConnectionString("IKekwBotWebAppContext");
    using(MySqlConnection con = new MySqlConnection(constr)) {
        string query = "SELECT `id`, `server_id`, `server_number`, `server_name`, `addr`, `tribe`, `relation`, `server-info` FROM `servers` WHERE id > " + startIndex + " ORDER BY `id` LIMIT 15";
        using(MySqlCommand cmd = new MySqlCommand(query)) {
            cmd.Connection = con;
            con.Open();
            using(MySqlDataReader sdr = cmd.ExecuteReader()) {
                while (sdr.Read()) {
                    serverList.Add(new ServerList {
                        Id = int.Parse(sdr.GetString(0)),
                        Server_id = int.Parse(sdr.GetString(1)),
                        Server_number = sdr.GetString(2),
                        Server_name = sdr.GetString(3),
                        Server_address = sdr.GetString(4),
                        Server_tribe = sdr.GetString(5),
                        Server_relation = sdr.GetString(6),
                        Server_Info = sdr.GetString(7)
                    });
                }
            }
            con.Close();
        }
    }

    return serverList;
}

通过将 React 和 Redux 与两个按钮相结合,我将索引传递给返回数据的控制器,但是,有时返回的数据是重复的或相同的,即使它应该是下一页。

React 代码(一小部分)

private renderServerListTable() {
        return (
            <table className='table table-striped' aria-labelledby="tabelLabel">
                <thead>
                    <tr>
                        <th>Server Number</th>
                        <th>Server Name</th>
                        <th>Server Address</th>
                        <th>Server Tribe</th>
                        <th>Server Relation</th>
                        <th>Server Info</th>
                    </tr>
                </thead>
                <tbody>
                    {this.props.serverLists.map((server: ServerListStore.ServerList) =>
                        <tr key={server.server_id}>
                            <td>{server.server_number}</td>
                            <td>{server.server_name}</td>
                            <td>{server.server_address}</td>
                            <td>{server.server_tribe}</td>
                            <td>{server.server_relation}</td>
                            <td>{server.server_Info}</td>
                        </tr>
                    )}
                </tbody>
            </table>
        );
    }

    private renderPagination() {
        const prevStartDateIndex = (this.props.startDateIndex || 0) - 15;
        const nextStartDateIndex = (this.props.startDateIndex || 0) + 15;

        return (
            <div className="d-flex justify-content-between">
                <Link className='btn btn-outline-secondary btn-sm' to={`/server-list/${prevStartDateIndex}`}>Previous</Link>
                {this.props.isLoading && <span>Loading...</span>}
                <Link className='btn btn-outline-secondary btn-sm' to={`/server-list/${nextStartDateIndex}`}>Next</Link>
            </div>
        );
    }

有什么建议更有效或更可靠的解决方案吗?

【问题讨论】:

    标签: c# mysql asp.net react-redux


    【解决方案1】:

    您对此问题的解决方案是,如果您的 id 值有索引,则非常接近理想值。

    查询模式

    SELECT stuff 
      FROM table
     WHERE indexedValue > startIndex 
     ORDER BY indexedValue
     LIMIT 10
    

    是尽可能高效的分页查询。它肯定比...ORDER BY indexedValue LIMIT 10 OFFSET startIndex 更有效率。

    如果您有办法对任意列进行排序,分页可能会比较棘手。

    【讨论】:

      【解决方案2】:

      我会删除WHERE 子句以支持OFFSETFETCH 功能来实现分页,因此我的查询将变成类似于:

      string query = "SELECT `id`, `server_id`, `server_number`, `server_name`, `addr`, `tribe`, `relation`, `server-info` FROM `servers` ORDER BY `id` OFFSET" + startIndex + " ROWS FETCH NEXT 15 ROWS;
      

      但是为了提高性能,在唯一列上搜索看起来确实是一种更好的方法。 My understanding is based on the following link .

      缓存页面边界也可以是一个解决方案:

      Cached Page Boundries

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-31
      • 1970-01-01
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多