Мне кажется, проблема как раз из-за большого количества диапазонов. Долго становится уже на этапе определения того, что сделал кассир: просканировал ШК товара, код или введенные данные являются картой. Диапазон тут играет роль общего идентификатора, если введенное на кассе, условно назовем "число" входит в диапазон карт, то откладываем поиск по всяким товарам и их шк, а работаем только с модулем карты. Далее уже непосредственно по связке номер карты - категория содержащая процент.
Для нормальной работы вам достаточно одного "огромного" диапазона ну или, скажем максимум нескольких десятков диапазонов, включающих все карты которые вы присоединяете к любой одной, назовем "базовой" категории. А далее грузите карты по принципу:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<cards-catalog>
<internal-card number="4810191713479" status="ACTIVE" deleted="False" percentage-discount="2"/>
<internal-card number="4810194810199" status="ACTIVE" deleted="False" percentage-discount="3"/>
<internal-card number="4810195109107" status="ACTIVE" deleted="False" percentage-discount="5"/>
</cards-catalog>
таким образом, SR сам создаст категории с нужным процентом, а карты к ним перепривяжутся, как будто бы был переход в другую категорию.
Это мое скромное понимание ситуации, может я и ошибаюсь. Посмотрите- попробуйте, может и прокатит такой вариант. Разумеется не забудьте сделать Бэкап))