【问题标题】:what's the best way to select data选择数据的最佳方式是什么
【发布时间】:2018-08-23 22:12:58
【问题描述】:

我有一个在线游戏,一切都很好,问题是当你登录服务器时选择数据需要太长时间,我使用mysql,我是新手,不知道有没有办法优化这个或者它只是很慢,就是这样。

这适用于 c# 和 mysql

        int UserId;
        DataRow dUserInfo = null;
        DataTable dAchievements = null;
        DataTable dFavouriteRooms = null;
        DataTable dIgnores = null;
        DataTable dBadges = null;
        DataTable dFriends = null;
        DataTable dRequests = null;
        DataTable dRooms = null;
        DataTable dQuests = null;
        DataTable dRelations = null;
        DataRow UserInfo = null;

        using (IQueryAdapter db = Progam.GetQueryReactor())
        {
            db.SetQuery("SELECT * " + "FROM users WHERE `auth_ticket` = @addr LIMIT 1");
            db.AddParameter("addr", SessionTicket);
            dUserInfo = db.getRow();

            UserId = Convert.ToInt32(dUserInfo["id"]);

            db.SetQuery("SELECT `group`,`level`,`progress` FROM `user_achievements` WHERE `userid` = '" + UserId + "'");
            dAchievements = db.getTable();

            db.SetQuery("SELECT room_id FROM user_favorites WHERE `user_id` = '" + UserId + "'");
            dFavouriteRooms = db.getTable();

            db.SetQuery("SELECT ignore_id FROM user_ignores WHERE `user_id` = '" + UserId + "'");
            dIgnores = db.getTable();

            db.SetQuery("SELECT `badge_id`,`badge_slot` FROM user_badges WHERE `user_id` = '" + UserId + "'");
            dBadges = db.getTable();

            db.SetQuery(
                "SELECT users.id,users.username,users.fb_name,users.motto,users.look,users.last_online,users.hide_inroom,users.hide_online " +
                "FROM users " +
                "JOIN messenger_friendships " +
                "ON users.id = messenger_friendships.user_one_id " +
                "WHERE messenger_friendships.user_two_id = " + UserId + " " +
                "UNION ALL " +
                "SELECT users.id,users.username,users.fb_name,users.motto,users.look,users.last_online,users.hide_inroom,users.hide_online " +
                "FROM users " +
                "JOIN messenger_friendships " +
                "ON users.id = messenger_friendships.user_two_id " +
                "WHERE messenger_friendships.user_one_id = " + UserId);
            dFriends = db.getTable();

            db.SetQuery("SELECT messenger_requests.from_id,messenger_requests.to_id,users.username FROM users JOIN messenger_requests ON users.id = messenger_requests.from_id WHERE messenger_requests.to_id = " + UserId);
            dRequests = db.getTable();

            db.SetQuery("SELECT * FROM rooms WHERE `user_id` = '" + UserId + "' ");
            dRooms = db.getTable();

            db.SetQuery("SELECT `q_id`,`progress` FROM user_quests WHERE `user_id` = '" + UserId + "'");
            dQuests = db.getTable();

            db.SetQuery("SELECT `id`,`user_id`,`target`,`type` FROM `user_relationships` WHERE `user_id` = '" + UserId + "'");
            dRelations = db.getTable();

            db.SetQuery("SELECT * FROM `user_info` WHERE `user_id` = '" + UserId + "' LIMIT 1");
            UserInfo = db.getRow();

            if (UserInfo == null)
            {
                db.RunQuery("INSERT INTO `user_info` (`user_id`) VALUES ('" + UserId + "')");

                db.SetQuery("SELECT * FROM `user_info` WHERE `user_id` = '" + UserId + "' LIMIT 1");
                UserInfo = db.getRow();
            }

            db.SetQuery("UPDATE `users` SET `online` = '1', `auth_ticket` = '', `machine_id` = @mid WHERE `id` = @hid LIMIT 1");
            db.AddParameter("mid", MachineId);
            db.AddParameter("hid", UserId);
            db.RunQuery();
        }

这需要很长时间(10 秒或更长时间)

【问题讨论】:

  • 1) 我会在所有查询中使用参数,2) 你有多达 14 个查询正在运行 - 不可能知道哪些查询可能很慢 3) 你在表上有索引吗? 4)添加日志记录或独立运行每个查询,看看哪些是慢的。
  • 首先,我会从第一个查询中删除*。据我们所知,如果没有您的表定义,您可能会检索到一个巨大的高分辨率用户照片 blob。
  • SELECT * FROM users WHERE auth_ticket = @addr LIMIT 1 奇怪的查询,因为。 SQL 是无序集。使用 LIMIT 1 而不使用 ORDER BY MySQL 不会总是在多次运行查询时保证相同的记录...但是当 auth_ticket 在表... 另请阅读有关防止 SQL 注入的信息,C# 确实支持准备好的语句以防止 SQL 注入

标签: c# mysql sql


【解决方案1】:

不要选择使用“*”的列。 '*' 返回所有列。如果您有很多 BLOB 列,那么它将停止运行,因为它会返回这些列。通过将它们全部列出来选择各个列,即使数量很大。

另外,我看不到来自您的服务器的响应是什么,但是如果您只返回一行,那么请考虑将多个查询组合成一个查询。如果您正在运行所有这些查询,那么您的系统将一个接一个地执行它们,这意味着您在程序等待所有响应时会有延迟。将所有查询组合成一个类似于下面的查询,因为 SQL 服务器将一次性获取所有响应,然后返回它们。

SELECT
(SELECT Column1 FROM DatabaseName1 WHERE Column2 = 'Something') AS Info1,
(SELECT Column1 FROM DatabaseName2 WHERE Column2 = 'Something') AS Info2,
(SELECT Column1 FROM DatabaseName3 WHERE Column2 = 'Something') AS Info3

【讨论】:

  • 我感觉很多OP的查询都有多个结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 2014-11-12
相关资源
最近更新 更多