Выбор всех строк с помощью SELECT *, но записи не полны

Проблема

У меня есть служба Go в качестве задания cron для проверки всех данных из таблицы базы данных раз в неделю. Логика очень проста: сервис Go извлекает все строки из исходной таблицы и выполняет некоторую логику с данными. Однако есть некоторая проблема: у меня есть 3.371.351 или ~3 миллиона строк и 400 столбцов из исходной таблицы, а я получаю только около 138.912 или ~100 тысяч строк (хранящихся в срезе Go), что указывает на то, что несколько строк не были получены полностью. по запросу, даже если процесс запроса успешно выполнен.

Код

Вот мой код Go, который выполняет простой оператор SELECT:

func (repository Repository) GetAllData() ([]entity.ExampleStruct, error) {
    sql := fmt.Sprintf("SELECT * FROM [%s].[schema_data].[%s]", viper.GetString("SQL_SERVER_DBNAME"), viper.GetString("SQL_SERVER_TABLE"))
    
    rows, err := repository.sqlServerConnection.Query(sql)
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    if rows.Err() != nil {
        return nil, rows.Err()
    }

    var exampleStructList []entity.ExampleStructList 
    for rows.Next() {
        var exampleStruct entity.ExampleStruct
        err := rows.Scan(// scan struct here)
        if err != nil {
            return nil, err
        }

        exampleStructList = append(exampleStructList , exampleStruct)
    }

    return exampleStructList, nil
}

Выводы

Раньше я сравнивал запрос с предложением WITH (NOLOCK), чтобы ускорить выполнение оператора SELECT, и без него, но, похоже, результаты остались такими же. Что интересно, я могу получить правильное количество строк, используя запрос COUNT(*). Я также получил информацию от моего администратора базы данных о том, что у них есть несколько операций восстановления в базе данных и таблице для обновления данных. Я предполагаю, что операция восстановления может повлиять на мой процесс выборки строк.

Иногда у меня возникала ошибка при получении данных, как показано ниже:

 "Error": {
  "Number": 927,
  "State": 6,
  "Class": 14,
  "Message": "Database 'xx' cannot be opened. It is in the middle of a restore.",
  "ServerName": "xx",
  "ProcName": "",
  "LineNo": 1,
  "All": [
   {
    "Number": 927,
    "State": 6,
    "Class": 14,
    "Message": "Database 'xx' cannot be opened. It is in the middle of a restore.",
    "ServerName": "xx",
    "ProcName": "",
    "LineNo": 1,
    "All": null
   }
  ]
}

ожидаемый результат

Мой ожидаемый результат: оператор SELECT должен возвращать полную запись с тем же количеством строк, что и исходная таблица. Например, если исходная таблица имеет 3 миллиона строк, я также должен получить ровно 3 миллиона строк из моего оператора SELECT *.

Спецификация

Вам следует прочитать и понять все последствия использования nolock, потому что вы когда-либо его использовали. Вряд ли это будет то, что вы думаете.

Dale K 17.04.2024 05:50

Записывает ли сервис какие-либо данные (обратно в ту же базу данных или куда-либо еще) или просто читает и проверяет? Если последнее, можете ли вы просто выполнить чтение и проверку в SQL (например, в хранимой процедуре)? 3 миллиона строк * 400 столбцов — это много данных, как насчет их пакетной обработки? Вам действительно нужны все 400 столбцов?

allmhuran 17.04.2024 05:52

@allmhuran мой сервис просто читает и проверяет все данные, ничего особенного. Можете ли вы дать мне представление о процессе пакетной обработки? это в коде Go? или на уровне SQL-запроса с использованием LIMIT? И да, мне нужны все колонки для нужд бизнеса

mathias yeremia 17.04.2024 05:53

@DaleK Я пытался его не использовать, но результат тот же.

mathias yeremia 17.04.2024 05:53

Я не имел в виду, что nolock имеет отношение к этой проблеме... просто к вашему сведению... не используйте его.

Dale K 17.04.2024 05:56

@DaleK Понятно, я возьму это на заметку. Итак, должно ли быть действие восстановления разрушает строки?

mathias yeremia 17.04.2024 05:57

То, как именно вам следует выполнять пакетную обработку, будет зависеть от вашей схемы. Общий шаблон таков: «используйте столбец (или несколько столбцов, если необходимо) для фильтрации и отслеживайте, что вы делаете». Используемые вами столбцы должны быть проиндексированы и уникальны. Если ваш кластерный индекс находится в чем-то вроде столбца identity, это прекрасно работает. На SO уже есть различные вопросы, посвященные этому, например здесь и здесь.

allmhuran 17.04.2024 06:02

Вам следует переместить проверку rows.Err() после цикла for rows.Next() { (вероятно, вы пропустили ошибку; ошибки могут возникнуть при получении результатов). См. документацию по базе данных/sql и этот пример.

Brits 17.04.2024 06:47

Это очень много данных, которые нужно сохранить в памяти. У меня такое ощущение, что сервис Go не подходит для решения этой задачи. Нельзя ли делать манипуляции с базой данных как процедуру, а потом позволить сервису ее вызвать?

siggemannen 17.04.2024 07:52

@allmhuran, хорошо, спасибо за ссылку, кажется, просто реализуем подход к нумерации страниц, если я не ошибаюсь.

mathias yeremia 17.04.2024 10:11

@Brits, я попробую переместить rows.Err() и посмотреть, что получится, спасибо

mathias yeremia 17.04.2024 10:12

@siggemannen, к сожалению, у меня нет доступа к базе данных, потому что она принадлежит другой команде

mathias yeremia 17.04.2024 10:23

И ты не можешь поговорить с этой командой? Какую логику вы вообще используете в своем сервисе? Вам нужно постоянно отслеживать все строки? Что произойдет, если вы просто «намотаете» строки, не сохраняя их, извлекается ли все или тоже забивается?

siggemannen 17.04.2024 10:35

@siggemannen Привет, я хочу сообщить вам новости: я связался с командой администраторов баз данных, чтобы они могли настроить время восстановления, и это действительно сработало. Я могу получить полную запись.

mathias yeremia 02.05.2024 03:39

@mathiasyeremia рада это слышать! совместная работа - хороший способ решить проблемы :)

siggemannen 02.05.2024 09:48
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
15
106
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решено: причина в активности восстановления, поэтому мне нужно получить данные, когда расписание восстановления отключено.

Другие вопросы по теме